it-swarm.com.de

Was ist der schnellste Weg, um alle Dateien und Unterordner in einem Verzeichnis zu entfernen?

Ein Programm hat viele verschachtelte Unterordner erstellt. Ich habe versucht, sie mit dem Befehl rm -fr * Zu entfernen. Aber es ist sehr langsam. Ich frage mich, ob es einen schnelleren Weg gibt, sie alle zu löschen.

18
Lei Hao

Der schnellste Weg, sie aus diesem Verzeichnis zu entfernen, besteht darin, sie von dort weg zu verschieben. Danach entfernen Sie sie einfach im Hintergrund:

mkdir ../.tmp_to_remove
mv -- * ../.tmp_to_remove
rm -rf ../.tmp_to_remove &

Dies setzt voraus, dass Ihr aktuelles Verzeichnis nicht die oberste Ebene einer bereitgestellten Partition ist (d. H., Dass ../.tmp_to_remove Auf demselben Dateisystem liegt).

Das -- Nach mv (wie von Stéphane bearbeitet) ist erforderlich, wenn Sie Datei-/Verzeichnisnamen haben, die mit einem - Beginnen.

Mit dem obigen Befehl werden die Dateien in Sekundenbruchteilen aus Ihrem aktuellen Verzeichnis entfernt, da die Unterverzeichnisse nicht rekursiv verarbeitet werden müssen. Das eigentliche Entfernen des Baums aus dem Dateisystem dauert länger, aber da er nicht im Weg ist, sollte seine tatsächliche Effizienz nicht so wichtig sein.

20
Anthon

rsync ist überraschend schnell und einfach. Sie müssen zuerst ein leeres Verzeichnis erstellen.

mkdir Emptydir 
 rsync -a --delete Emptydir/yourdirectory /

yourdirectory/ ist das Verzeichnis, aus dem Sie die Dateien entfernen möchten.

17
Rahul

Ein Problem mit _rm -rf *_ oder dem korrekteren Äquivalent _rm -rf -- *_ besteht darin, dass die Shell zuerst alle (nicht versteckten) Dateien im aktuellen Verzeichnis auflisten, sortieren und an rm, was, wenn die Liste der Dateien im aktuellen Verzeichnis groß ist, unnötigen zusätzlichen Aufwand verursacht und sogar fehlschlagen kann, wenn die Liste der Dateien zu groß ist.

Normalerweise würden Sie stattdessen _rm -rf ._ ausführen (was auch den Vorteil hätte, versteckte Dateien zu löschen). Die meisten rm -Implementierungen, einschließlich aller POSIX-konformen, werden dies jedoch ablehnen. Der Grund ist, dass einige Shells (einschließlich aller POSIX-Shells) die Fehlfunktion haben, dass die Erweiterung von _.*_ glob _._ und _.._ umfassen würde. Was bedeuten würde, dass _rm -rf .*_ das aktuelle und das übergeordnete Verzeichnis löschen würde, sodass rm geändert wurde, um diese Fehlfunktion dieser Shells zu umgehen.

Einige Shells wie pdksh (und andere Forsyth Shell-Derivate), zsh oder fish haben diese Fehlfunktion nicht. zsh verfügt über ein integriertes rm, das Sie mit _autoload zsh/files_ aktivieren können, da _.*_ von zsh _._ nicht enthält noch _.._ funktioniert einwandfrei mit _rm -rf ._. In zsh können Sie also Folgendes tun:

_autoload zsh/files
rm -rf .
_

Unter Linux können Sie Folgendes tun:

_rm -rf /proc/self/cwd/
_

um das aktuelle Verzeichnis zu leeren oder:

_rm -rf /dev/fd/3/ 3< some/dir
_

ein beliebiges Verzeichnis leeren.

(Beachten Sie das nachfolgende _/_)

Auf GNU Systemen) können Sie Folgendes tun:

_find . -delete
_

Wenn das aktuelle Verzeichnis nur wenige Einträge enthält und sich der Großteil der Dateien in Unterverzeichnissen befindet, macht dies keinen wesentlichen Unterschied, und _rm -rf -- *_ ist wahrscheinlich der schnellste, den Sie erhalten können. Es wird erwartet, dass _rm -rf_ (oder alles, was jede Datei entfernt) teuer ist, da dies bedeutet, den Inhalt aller Verzeichnisse zu lesen und unlink() für jeden Eintrag aufzurufen. unlink() selbst kann sehr teuer sein, da der Inode der gelöschten Datei, das Verzeichnis, in dem sich die Datei befindet, und eine Dateisystemzuordnung oder andere freie Bereiche geändert werden müssen.

rm und find (zumindest die GNU Implementierungen) sortieren die Liste der Dateien bereits nach Inode-Nummer in jedem Verzeichnis, was einen großen Unterschied in Bezug auf machen kann Leistung auf ext4-Dateisystemen, da dadurch die Anzahl der Änderungen an den zugrunde liegenden Blockgeräten verringert wird, wenn aufeinanderfolgende (oder nahe beieinander liegende) Inodes nacheinander geändert werden.

rsync sortiert die Dateien nach Namen, was die Leistung drastisch verringern könnte, es sei denn, die Reihenfolge nach Namen stimmt mit der Reihenfolge nach Zahlen überein (z. B. wenn die Dateien aus einer sortierten Liste von Dateinamen erstellt wurden).

Ein Grund, warum rsync in einigen Fällen schneller sein kann, besteht darin, dass anscheinend keine Sicherheitsvorkehrungen getroffen werden, um Rennbedingungen zu vermeiden, die dazu führen könnten, dass das Verzeichnis in das falsche Verzeichnis verschoben wird, wenn ein Verzeichnis währenddessen durch einen Symlink ersetzt wird Arbeiten wie rm oder find.

Um etwas weiter zu optimieren:

Wenn Sie die maximale Tiefe Ihres Verzeichnisbaums kennen, können Sie diese an find übergeben:

_find . -maxdepth 3 -delete
_

Das erspart find den Versuch, den Inhalt der Verzeichnisse in Tiefe 3 zu lesen.

9

Das schnellste ist mit rm -rf dirname. Ich habe einen Snapshot-Mountpunkt eines ext3-Dateisystems auf RedHat6.4 mit 140520-Dateien und 9699-Verzeichnissen verwendet. Wenn rm -rf * ist langsam, möglicherweise liegt es daran, dass Ihr Verzeichniseintrag der obersten Ebene viele Dateien enthält und die Shell gerade mit der Erweiterung von *, was ein zusätzliches Readdir und Sortieren erfordert. Gehen Sie in ein Verzeichnis und machen Sie rm -rf dirname/.

Method                    Real time    Sys time  Variance (+/-)
find dir -delete          0m8.108s     0m3.668s  0.055s
rm -rf dir                0m7.956s     0m3.640s  0.081s
rsync -delete empty/ dir/ 0m8.305s     0m3.918s  0.029s

Anmerkungen:

  • rsync version: 3.0.6
  • rm/coreutils version: 8.4-19
  • find/findutils version: 4.4.2-6
7
Otheus