Eliminare miliardi di file da una directory e vedere anche i progressi


36

Ho una directory di 30 TB che contiene miliardi di file che sono formalmente tutti i file JPEG. Sto eliminando ogni cartella di file in questo modo:

sudo rm -rf bolands-mills-mhcptz

Questo comando viene eseguito e non mostra nulla, sia che funzioni o meno.

Voglio vedere come sta eliminando i file o qual è lo stato corrente del comando.


19
Non risponde: a volte è più veloce eseguire il backup degli elementi che si desidera conservare, formattare e ripristinare gli elementi che si desidera conservare. Altre risposte: unix.stackexchange.com/questions/37329/…
Eric Towers

2
Se vuoi solo un'idea di progresso, piuttosto che sapere quali file particolari sono stati rimossi, potresti eseguire "df / dev / sd_whatever_the_drive_is".
jamesqf,

11
Come sei finito con miliardi di file in una singola directory ??
Lightness Races con Monica

1
@MichaelHampton Ma se i file non sono un set di dati separato, potrebbe richiedere molto tempo. (su ZFS) serverfault.com/questions/801074/…
v7d8dpo4

5
Miliardi di file, eh? Prova rm -ri. Sarà divertente!
OldBunny2800,

Risposte:


98

È possibile utilizzare rm -vper avere rmstampare una riga per ogni file cancellato. In questo modo puoi vedere che rmfunziona davvero per eliminare i file. Ma se hai miliardi di file, tutto ciò che vedrai è che rmfunziona ancora. Non avrai idea di quanti file siano già stati eliminati e quanti ne siano rimasti.

Lo strumento pvpuò aiutarti con una stima dei progressi.

http://www.ivarch.com/programs/pv.shtml

Ecco come invocheresti rmcon l' pvoutput di esempio

$ rm -rv dirname | pv -l -s 1000 > logfile
562  0:00:07 [79,8 /s] [====================>                 ] 56% ETA 0:00:05

In questo esempio inventato ho detto pvche ci sono 1000file. L'output di pvmostra che 562 sono già stati eliminati, il tempo trascorso è di 7 secondi e la stima da completare è in 5 secondi.

Qualche spiegazione:

  • pv -lfa pvcontare per newline anziché byte
  • pv -s numberindica pvqual è il totale in modo che possa fornirti una stima.
  • Il reindirizzamento alla logfilefine è per l'output pulito. Altrimenti la riga di stato da pvviene confusa con l'output di rm -v. Bonus: avrai un file di log di ciò che è stato eliminato. Ma attenzione, il file diventerà enorme. Puoi anche reindirizzare a /dev/nullse non hai bisogno di un registro.

Per ottenere il numero di file è possibile utilizzare questo comando:

$ find dirname | wc -l

Anche questo può richiedere molto tempo se ci sono miliardi di file. Puoi usare anche pvqui per vedere quanto ha contato

$ find dirname | pv -l | wc -l
278k 0:00:04 [56,8k/s] [     <=>                                              ]
278044

Qui dice che ci sono voluti 4 secondi per contare 278k file. Il conteggio esatto alla fine ( 278044) è l'output di wc -l.

Se non si desidera attendere il conteggio, è possibile indovinare il numero di file o utilizzare pvsenza stima:

$ rm -rv dirname | pv -l > logfile

In questo modo non avrai alcuna stima da terminare ma almeno vedrai quanti file sono già stati eliminati. Reindirizzare a /dev/nullse non è necessario il file di registro.


nitpick:

  • hai davvero bisogno sudo?
  • di solito rm -rè sufficiente per eliminare in modo ricorsivo. non c'è bisogno di rm -f.

5
Un buon uso di pv, supponendo che non sia troppo costoso contare i miliardi di file ;-). (Potrebbe richiedere quasi tutto il tempo rmche dovrebbe misurare!)
Stephen Kitt

7
@StephenKitt Questo è ciò che mi infastidisce davvero (e molte altre persone) dell'utilità dei file di Windows: conta sempre , a colpo sicuro, il numero e le dimensioni dei file prima di eliminarli che, a meno che l'unità non sia molto più lenta del processore, richiede quasi purché l'effettiva cancellazione!
wizzwizz4,

@ wizzwizz4 In effetti! C'è di più in questo, sebbene IIRC - controlla che possa eliminare tutto prima di eliminare qualsiasi cosa , per aumentare le possibilità che le eliminazioni siano "tutto o niente". Molti anni fa ho scritto un driver per filesystem per Windows, c'erano alcune stranezze che dovevamo affrontare, tra cui alcune relative al modo in cui Explorer esegue l'eliminazione, ma non ricordo i dettagli. (Ricordo che la creazione di una cartella comporta la scrittura e l'eliminazione di un file nella nuova cartella!)
Stephen Kitt,

7
@StephenKitt Forse mi sbaglio, ma non è il collo di bottiglia, oltre all'accesso al disco, l'output del terminale? Credo che pvaggiorni la barra di avanzamento solo una volta al secondo, nonostante il suo input. Pertanto, il terminale deve solo visualizzare una riga anziché una tonnellata al secondo. pvdeve solo incrementare un contatore per ogni newline che incontra; deve essere più veloce di fare il wrapping di linea e quant'altro per visualizzare una linea in un terminale. Penso che correre pvcosì sia che la rimozione dei file sia più rapida della semplice rm -rv.
JoL

1
@skywinderrm -rv dirname | pv -l -s $(find dirname | wc -l) > logfile
lesmana,

28

Scopri la risposta di Lesmana , è molto migliore del mio - in particolare l'ultimo pvesempio, che non avrà molto più lungo del silenzio originale rmse si specifica /dev/nullal posto di logfile.

Supponendo che rml'opzione supporti (probabilmente lo fa da quando si esegue Linux), è possibile eseguirla in modalità dettagliata con -v:

sudo rm -rfv bolands-mills-mhcptz

Come è stato sottolineato da numerosi commentatori, questo potrebbe essere molto lento a causa della quantità di output generato e visualizzato dal terminale. È possibile invece reindirizzare l'output su un file:

sudo rm -rfv bolands-mills-mhcptz > rm-trace.txt

e guarda le dimensioni di rm-trace.txt.


5
Questo può effettivamente rallentare la cancellazione a causa di tutto l'output generato e sottoposto a rendering su un terminale :)
rackandboneman

2
Naturalmente rallenterà. La scrittura di miliardi di righe su un file non avviene in tempi zero.
user207421

23

Un'altra opzione è vedere diminuire il numero di file nel filesystem. In un altro terminale, eseguire:

watch  df -ih   pathname

Il conteggio degli inode usati diminuirà man mano rmche avanza. (A meno che i file non contengano principalmente più collegamenti, ad esempio se l'albero è stato creato con cp -al). Tiene traccia dell'avanzamento dell'eliminazione in termini di numero di file (e directory). dfsenza -iseguirà in termini di spazio utilizzato.

Potresti anche correre iostat -x 4per vedere le operazioni di I / O al secondo (così come kiB / s, ma non è molto rilevante per l'I / O di metadati puri).


Se sei curioso di sapere su quali file rmsta lavorando, puoi collegarlo stracee guardare come il sistema unlink()(e getdents) chiama il tuo terminale. es sudo strace -p $(pidof rm). Puoi ^clo strace da cui staccarti rmsenza interromperlo.

Dimentico se la rm -rdirectory delle modifiche nell'albero viene eliminata; se così potessi guardare /proc/<PID>/cwd. La sua /proc/<PID>/fdforza, spesso hanno una directory fd aperto, quindi si poteva guardare che per vedere che cosa il vostro rmprocesso è attualmente esaminando.


2
df -ihè davvero un bel modo economico di vedere i rmprogressi.
Stephen Kitt,

A proposito, questo non funziona su BTRFS, dove il conteggio dell'inode usato è sempre zero. :( Lo stesso per FAT32, ma probabilmente non hai miliardi di file sulla tua /bootpartizione di sistema EFI.
Peter Cordes

4

Mentre le risposte di cui sopra sono tutte utilizzabili rm, in rmrealtà può essere piuttosto lento nell'eliminare un gran numero di file, come ho recentemente osservato durante l'estrazione di file ~ 100K da un archivio .tar in realtà ci è voluto meno tempo rispetto all'eliminazione di essi. Sebbene questo non risponda effettivamente alla domanda che hai posto, una soluzione migliore al tuo problema potrebbe essere quella di utilizzare un metodo diverso per eliminare i tuoi file, come una delle risposte votate a questa domanda .

Il mio metodo preferito personale è usare rsync -a --delete. Trovo che questo metodo funzioni abbastanza velocemente da valere la facilità d'uso rispetto alla risposta più votata a quella domanda , in cui l'autore ha scritto un programma C che dovresti compilare. (Si noti che questo produrrà tutti i file che vengono elaborati su stdout, molto simile rm -rv; questo può rallentare il processo di una quantità sorprendente. Se non si desidera questo output, utilizzare invece rsync -aq --deleteo reindirizzare l'output su un file.)

L'autore di quella risposta dice:

Il programma ora (sul mio sistema) eliminerà 1000000 file in 43 secondi. Il programma più vicino a questo è stato rsync -a --delete che ha richiesto 60 secondi (che esegue anche le eliminazioni in ordine, ma non esegue una ricerca di directory efficiente).

Ho scoperto che questo è abbastanza buono per i miei scopi. Anche potenzialmente importante da quella risposta, almeno se stai usando ext4:

Come previsto, si dovrebbe rimuovere la directory interessata e rifarla dopo. Le directory aumentano sempre solo di dimensioni e possono rimanere scarsamente performanti anche con pochi file all'interno a causa delle dimensioni della directory.


eh, mi sarei aspettato rme / o find --deleteessere efficiente. Punto interessante sull'eliminazione in ordine per evitare riequilibri b-tree durante l'eliminazione. Non sono sicuro di quanto si applica ad altri filesystem. XFS non è eccezionale con milioni di file per directory. IDK su BTRFS, ma ho l'impressione che potrebbe essere buono per quel genere di cose.
Peter Cordes,


@Menasheh Bene, l'ho modificato nella mia risposta.
Hitechcomputergeek il

3

Una cosa che potresti fare sarebbe avviare il rmprocesso in background (senza output, quindi non verrà rallentato) e quindi monitorarlo in primo piano con un semplice comando (a) :

pax> ( D=/path/to/dir ; rm -rf $D & while true ; do
...>   if [[ -d $D ]] ; then
...>     echo "$(find $D | wc -l) items left"
...>   else
...>     echo "No items left"
...>     break
...>   fi
...>   sleep 5
...> done )

27912 items left
224 items left
No items left

pax> _

La find/wccombo potrebbe essere sostituita con qualsiasi strumento in grado di darti le unità che desideri.


(a) Beh, relativamente semplice, rispetto, per esempio, alla fisica nucleare, all'ipotesi di Riemann, o cosa comprare mia moglie per Natale :-)


0

Qualche tempo fa ho scritto qualcosa per stampare la velocità con cui sono state stampate le linee. È possibile eseguire rm -rfv | ./countere stamperà le linee al secondo / min. Anche se non è un progresso diretto, ti darà un feedback sulla velocità di avanzamento, forse il rmvagabondaggio in un filesystem di rete o simile forse?

Il link al codice è qui:

http://www.usenix.org.uk/code/counter-0.01.tar.gz

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.