Come si trovano file di grandi dimensioni che sono stati eliminati ma sono ancora aperti in un'applicazione? Come si può rimuovere un file del genere, anche se un processo lo ha aperto?
La situazione è che stiamo eseguendo un processo che sta riempiendo un file di registro a una velocità eccezionale. Conosco il motivo e posso risolverlo. Fino ad allora, vorrei ripristinare o svuotare il file di registro senza arrestare il processo.
Semplicemente facendo rm output.log
rimuove solo i riferimenti al file, ma continua a occupare spazio su disco fino al termine del processo. Peggio:dopo rm
Ora non ho modo di trovare dove sia il file o quanto sia grande! C'è un modo per trovare il file ed eventualmente svuotarlo, anche se è ancora aperto in un altro processo?
Mi riferisco in particolare ai sistemi operativi basati su Linux come Debian o RHEL.
Risposta accettata:
Se non riesci a terminare la tua applicazione, puoi troncare invece di eliminare il file di registro per recuperare lo spazio. Se il file non era aperto in modalità append (con O_APPEND
), quindi il file apparirà grande come prima la prossima volta che l'applicazione vi scriverà (sebbene con la parte iniziale sparsa e sembrando che contenesse byte NUL), ma lo spazio sarà stato recuperato (che non si applica a HFS+ file system su Apple OS/X che però non supportano i file sparsi).
Per troncarlo:
: > /path/to/the/file.log
Se era già stato cancellato, su Linux, puoi comunque troncarlo facendo:
: > "/proc/$pid/fd/$fd"
Dove $pid
è l'id del processo che ha aperto il file e $fd
un descrittore di file in cui lo ha aperto (che puoi controllare con lsof -p "$pid"
.
Se non conosci il pid e stai cercando file cancellati, puoi fare:
lsof -nP | grep '(deleted)'
lsof -nP +L1
, come menzionato da @user75021 è un'opzione ancora migliore (più affidabile e più portabile) (elenca i file che hanno meno di 1 collegamento).
Oppure (su Linux):
find /proc/*/fd -ls | grep '(deleted)'
O per trovare quelli grandi con zsh
:
ls -ld /proc/*/fd/*(-.LM+1l0)
Un'alternativa, se l'applicazione è collegata dinamicamente, è allegare ad essa un debugger e fargli chiamare close(fd)
seguito da un nuovo open("the-file", ....)
.