Milliarden von Dateien aus einem Verzeichnis löschen und dabei den Fortschritt mitverfolgen


36

Ich habe ein Verzeichnis von 30 TB mit Milliarden von Dateien, die formal alle JPEG-Dateien sind. Ich lösche jeden Ordner mit Dateien wie folgt:

sudo rm -rf bolands-mills-mhcptz

Dieser Befehl wird nur ausgeführt und zeigt nichts an, ob er funktioniert oder nicht.

Ich möchte sehen, wie Dateien gelöscht werden oder wie der aktuelle Status des Befehls lautet.


19
Keine Antwort: Manchmal ist es schneller, die Daten zu sichern, zu formatieren und wiederherzustellen, die Sie behalten möchten. Andere Antworten: unix.stackexchange.com/questions/37329/…
Eric Towers

2
Wenn Sie nur eine Vorstellung vom Fortschritt haben möchten, anstatt zu wissen, welche bestimmten Dateien entfernt wurden, können Sie "df / dev / sd_whatever_the_drive_is" ausführen.
Jamesqf

11
Wie sind Sie zu Milliarden von Dateien in einem einzigen Verzeichnis gekommen?
Leichtigkeit Rennen mit Monica

1
@MichaelHampton Aber wenn die Dateien kein separater Datensatz sind, kann es lange dauern. (unter ZFS) serverfault.com/questions/801074/…
v7d8dpo4

5
Milliarden von Dateien, nicht wahr? Versuchen Sie es rm -ri. Es wird Spaß machen!
OldBunny2800

Antworten:


98

Sie können verwenden rm -vhaben rmeine Zeile gedruckt werden pro Datei gelöscht. Auf diese Weise können Sie sehen, dass rmdas Löschen von Dateien tatsächlich funktioniert. Aber wenn Sie Milliarden von Dateien haben, ist alles, was Sie sehen werden, dass rmes noch funktioniert. Sie werden keine Ahnung haben, wie viele Dateien bereits gelöscht wurden und wie viele noch übrig sind.

Das Tool pvkann Ihnen bei einer Fortschrittsabschätzung helfen.

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

Hier ist , wie Sie aufrufen würde rmmit pvmit Beispielausgabe

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

In diesem erfundenen Beispiel habe ich gesagt, pvdass es 1000Dateien gibt. Die Ausgabe von pvzeigt, dass 562 bereits gelöscht wurden, die verstrichene Zeit 7 Sekunden beträgt und die Schätzung für den Abschluss 5 Sekunden beträgt.

Einige Erklärungen:

  • pv -lmacht pvdurch Zeilenumbrüche statt Bytes zu zählen
  • pv -s numbergibt an, wie pvhoch die Gesamtsumme ist, damit Sie eine Schätzung erhalten.
  • Die Umleitung nach logfileam Ende dient der sauberen Ausgabe. Andernfalls wird die Statuszeile von pvmit der Ausgabe von verwechselt rm -v. Bonus: Sie erhalten eine Protokolldatei von dem, was gelöscht wurde. Aber Vorsicht, die Datei wird riesig. Sie können auch weiterleiten, /dev/nullwenn Sie kein Protokoll benötigen.

Um die Anzahl der Dateien zu ermitteln, können Sie diesen Befehl verwenden:

$ find dirname | wc -l

Dies kann auch bei Milliarden von Dateien sehr lange dauern. Sie können auch pvhier sehen, wie viel es gezählt hat

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

Hier heißt es, dass es 4 Sekunden gedauert hat, bis 278k Dateien gezählt wurden. Die genaue Anzahl am Ende ( 278044) ist die Ausgabe von wc -l.

Wenn Sie nicht auf die Zählung warten möchten, können Sie entweder die Anzahl der Dateien erraten oder pvohne Schätzung verwenden:

$ rm -rv dirname | pv -l > logfile

Auf diese Weise haben Sie keine Schätzung für den Abschluss, aber Sie werden zumindest sehen, wie viele Dateien bereits gelöscht wurden. Weiterleiten an, /dev/nullwenn Sie die Protokolldatei nicht benötigen.


Nitpick:

  • Haben Sie wirklich brauchen sudo?
  • In der Regel reicht rm -res aus, rekursiv zu löschen. keine Notwendigkeit für rm -f.

5
Gute Verwendung von pv, vorausgesetzt, es ist nicht zu teuer, die Milliarden von Dateien zu zählen ;-). (Es könnte fast so lange dauern, wie rmes messen soll!)
Stephen Kitt

7
@StephenKitt Das ist , was mich wirklich nervt (und viele andere Menschen) über die Windows - Datei - Dienstprogramm: es immer unfehlbar, zählt die Anzahl und Größe der Dateien vor dem Löschen , die, es sei denn , das Laufwerk ist viel langsamer als der Prozessor, nimmt fast so solange die tatsächliche Löschung!
wizzwizz4

@ wizzwizz4 In der Tat! Es gibt mehr, als dass , obwohl IIRC - es überprüft, ob es kann alles vor dem Löschen zu löschen alles , um die Chancen von Löschungen zu erhöhen „alles oder nichts“ zu sein. Vor vielen Jahren habe ich einen Dateisystemtreiber für Windows geschrieben. Es gab einige Kuriositäten, mit denen wir uns befassen mussten, darunter einige, die mit dem Löschen durch Explorer zusammenhängen, aber ich kann mich nicht an die Details erinnern. (Ich erinnere mich, dass das Erstellen eines Ordners das Schreiben und Löschen einer Datei in dem neuen Ordner beinhaltet!)
Stephen Kitt

7
@StephenKitt Vielleicht irre ich mich, aber ist der Engpass neben dem Festplattenzugriff nicht auch die Terminalausgabe? Ich glaube, pvder Fortschrittsbalken wird trotz Eingabe nur einmal pro Sekunde aktualisiert. Das Terminal muss also nur eine Zeile anstatt einer Tonne pro Sekunde anzeigen. pvEs muss nur ein Zähler für jede neue Zeile erhöht werden, auf die es stößt. Das muss schneller sein als Zeilenumbrüche, und was auch immer, um eine Zeile in einem Terminal anzuzeigen. Ich denke, dass das Laufen mit pvso etwas dazu führt, dass das Entfernen von Dateien schneller als einfach ist rm -rv.
JoL

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

28

Schauen Sie sich die Antwort von Lesmana an , sie ist viel besser als meine - besonders das letzte pvBeispiel, das nicht viel länger dauert als die ursprüngliche Stille, rmwenn Sie /dev/nullanstelle von angeben logfile.

Vorausgesetzt, Sie rmunterstützen die Option (wahrscheinlich, weil Sie Linux verwenden), können Sie sie im ausführlichen Modus ausführen mit -v:

sudo rm -rfv bolands-mills-mhcptz

Wie von einer Reihe von Kommentatoren herausgestellt wurde, kann dies aufgrund der vom Terminal erzeugten und angezeigten Ausgabemenge sehr langsam sein. Sie können die Ausgabe stattdessen in eine Datei umleiten:

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

und beobachte die Größe von rm-trace.txt.


5
Dies kann das Löschen verlangsamen, da die gesamte Ausgabe generiert und an ein Terminal gerendert wird :)
rackandboneman

2
Natürlich wird es langsamer. Das Schreiben von Milliarden von Zeilen in eine Datei erfolgt nicht in null Zeit.
user207421

23

Eine andere Möglichkeit besteht darin, zu beobachten, wie die Anzahl der Dateien im Dateisystem abnimmt. Führen Sie in einem anderen Terminal Folgendes aus:

watch  df -ih   pathname

Die Anzahl der verwendeten Inodes nimmt mit zunehmendem rmFortschritt ab. (Es sei denn, die Dateien hatten meist mehrere Links, zB wenn der Baum mit erstellt wurde cp -al). Hiermit wird der Löschfortschritt in Bezug auf die Anzahl der Dateien (und Verzeichnisse) verfolgt. dfohne -iwird in Bezug auf den genutzten Platz nachverfolgt.

Sie können auch iostat -x 4E / A-Vorgänge pro Sekunde anzeigen (sowie kiB / s, dies ist jedoch für reine Metadaten-E / A nicht sehr relevant).


Wenn Sie neugierig werden, an welchen Dateien rmgerade gearbeitet wird, können Sie eine anhängen straceund beobachten, wie die unlink()Systemaufrufe (und getdents) auf Ihrem Terminal ausgelöst werden. zB sudo strace -p $(pidof rm). Sie können sich von ^cder Straße lösen, rmohne sie zu unterbrechen.

Ich vergesse, wenn das rm -rVerzeichnis in dem Baum geändert wird, der gelöscht wird. wenn ja könntest du dir anschauen /proc/<PID>/cwd. Seine /proc/<PID>/fdMacht hat oft ein Verzeichnis fd geöffnet, so dass Sie sich darum kümmern könnten , um zu sehen , was Ihr rmProzess zur Zeit betrachtet.


2
df -ihist in der Tat eine schöne billige Möglichkeit, den rmFortschritt zu beobachten .
Stephen Kitt

Übrigens funktioniert dies nicht bei BTRFS, wo die Anzahl der verwendeten Inodes immer Null ist. :( Dasselbe für FAT32, aber Sie haben wahrscheinlich nicht Milliarden von Dateien auf Ihrer /bootEFI-Systempartition.
Peter Cordes

4

Während die obigen Antworten alle verwenden rm, rmkann das Löschen einer großen Anzahl von Dateien tatsächlich ziemlich langsam sein, wie ich kürzlich beim Extrahieren von ~ 100K-Dateien aus einem .tar-Archiv festgestellt habe, dass das Löschen tatsächlich weniger Zeit in Anspruch nahm als das Löschen. Obwohl dies die von Ihnen gestellte Frage nicht beantwortet, besteht eine bessere Lösung für Ihr Problem möglicherweise darin, eine andere Methode zum Löschen Ihrer Dateien zu verwenden, z. B. eine der aktualisierten Antworten auf diese Frage .

Meine persönliche Lieblingsmethode ist zu verwenden rsync -a --delete. Ich bin der Meinung , dass diese Methode schnell genug ist, um die einfachste und am besten bewertete Antwort auf die Frage zu finden , in der der Autor ein C-Programm geschrieben hat, das Sie kompilieren müssten. (Beachten Sie, dass dadurch jede zu verarbeitende Datei ähnlich wie in stdout ausgegeben wird rm -rv. Dies kann den Prozess überraschend verlangsamen. Wenn Sie diese Ausgabe nicht möchten, verwenden Sie rsync -aq --deletestattdessen die Ausgabe oder leiten Sie sie in eine Datei um.)

Der Autor dieser Antwort sagt:

Das Programm löscht nun (auf meinem System) 1000000 Dateien in 43 Sekunden. Das Programm, das diesem am nächsten kam, war rsync -a --delete, das 60 Sekunden dauerte (das auch Löschvorgänge in der angegebenen Reihenfolge ausführt, jedoch keine effiziente Verzeichnissuche durchführt).

Ich habe festgestellt, dass dies für meine Zwecke gut genug ist. Auch potenziell wichtig aus dieser Antwort, zumindest wenn Sie ext4 verwenden:

Aus Vorsichtsgründen sollte man das betroffene Verzeichnis entfernen und es anschließend neu erstellen. Verzeichnisse nehmen immer nur an Größe zu und können aufgrund der Größe des Verzeichnisses auch mit wenigen darin enthaltenen Dateien eine schlechte Leistung aufweisen.


huh, ich hätte erwartet rmund / oder find --deleteeffizient zu sein. Interessanter Punkt zum Löschen in Sortierreihenfolge, um B-Tree-Neuverteilungen beim Löschen zu vermeiden. Nicht sicher, wie viel davon auf andere Dateisysteme zutrifft. XFS eignet sich auch nicht für Millionen von Dateien pro Verzeichnis. IDK über BTRFS, aber ich habe den Eindruck, dass es für so etwas gut sein könnte.
Peter Cordes

Hängt das zweite Zitat nicht von der Art des Dateisystems ab ...
Menasheh

@Menasheh Guter Punkt, das habe ich in meine Antwort eingearbeitet.
Hitechcomputergeek

3

Eine Möglichkeit wäre, den rmProzess im Hintergrund zu starten (ohne Ausgabe, damit er nicht verlangsamt wird) und ihn dann im Vordergrund mit einem einfachen Befehl (a) zu überwachen :

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> _

Die find/wcKombination kann durch ein beliebiges Werkzeug ersetzt werden, mit dem Sie die gewünschten Einheiten erhalten.


(a) Naja, relativ einfach im Vergleich zur Kernphysik, der Riemann-Hypothese oder was ich meiner Frau für Weihnachten kaufen soll :-)


0

Vor einiger Zeit habe ich etwas geschrieben, um die Rate zu drucken, mit der Zeilen gedruckt wurden. Du kannst rennen rm -rfv | ./counterund es werden Zeilen pro Sekunde / Minute gedruckt. Obwohl dies kein direkter Fortschritt ist, gibt es Ihnen ein Feedback zur Fortschrittsrate, vielleicht ist es rmin ein Netzwerk-Dateisystem gewandert oder ähnliches?

Der Link zum Code ist hier:

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.