Jak lze najít velké soubory, které byly smazány, ale jsou stále otevřené v aplikaci? Jak lze odstranit takový soubor, i když jej proces má otevřený?
Situace je taková, že běží proces, který plní log soubor ohromnou rychlostí. Znám důvod a mohu ho opravit. Do té doby bych chtěl rm nebo vyprázdnit soubor protokolu bez ukončení procesu.
Jednoduše uděláte rm output.log
odstraní pouze odkazy na soubor, ale nadále zabírá místo na disku, dokud není proces ukončen. Horší:po rm
Nyní nemám žádný způsob, jak zjistit, kde je soubor nebo jak je velký! Existuje nějaký způsob, jak najít soubor a případně jej vyprázdnit, i když je stále otevřený v jiném procesu?
Konkrétně mám na mysli operační systémy založené na Linuxu, jako je Debian nebo RHEL.
Přijatá odpověď:
Pokud nemůžete svou aplikaci ukončit, můžete místo odstranění souboru protokolu zkrátit, abyste získali místo zpět. Pokud soubor nebyl otevřen v režimu připojení (pomocí O_APPEND
), pak se soubor při příštím zápisu aplikace bude jevit tak velký jako předtím (ačkoli s úvodní částí řídkou a vypadá, jako by obsahoval NUL bajty), ale místo bude uvolněno (to neplatí pro HFS+ souborové systémy na Apple OS/X, které však nepodporují řídké soubory).
Chcete-li jej zkrátit:
: > /path/to/the/file.log
Pokud již byla smazána, na Linuxu ji stále můžete zkrátit takto:
: > "/proc/$pid/fd/$fd"
Kde $pid
je id procesu, který má soubor otevřený, a $fd
jeden deskriptor souboru, pod kterým je otevřen (což můžete zkontrolovat pomocí lsof -p "$pid"
.
Pokud neznáte pid a hledáte smazané soubory, můžete:
lsof -nP | grep '(deleted)'
lsof -nP +L1
, jak uvádí @user75021, je ještě lepší (spolehlivější a přenosnější) možnost (seznam souborů, které mají méně než 1 odkaz).
Nebo (v systému Linux):
find /proc/*/fd -ls | grep '(deleted)'
Nebo najít ty velké pomocí zsh
:
ls -ld /proc/*/fd/*(-.LM+1l0)
Alternativou, pokud je aplikace dynamicky propojená, je připojit k ní debugger a zavolat close(fd)
následovaný novým open("the-file", ....)
.