Wie geht rm -r beim rekursiven Entfernen vor? In welcher Reihenfolge?

30

Gibt es eine Reihenfolge für Operationen rm? Ich habe rmin einem großen Verzeichnis gespielt und bin gespannt, wo ich nachsehen soll, was möglicherweise gelöscht wurde. Arbeitet man zuerst rman Dateien, dann an Verzeichnissen? Oder basiert es auf Informationen in der Inode-Tabelle?

Technische Daten: rm vom GNU Coreutils 8.22-System: Arch Linux, das auf einem Beagleboneblack-Dateisystem läuft, war eine externe Seagate-Festplatte (ext4) mit USB 2.0.

Hintergrundgeschichte:

Ich habe einige Verzeichnisbereinigungen durchgeführt und durchgeführt

cp -r A/ B/ C/ Dest/

Unbeabsichtigt folgte ich dem mit

rm -r A/ B/ C/ Dest/

als ich einfach auftreten wollte

rm -r A/ B/ C/

Ich habe das abgefangen und Ctrl+ gedrückt, Cbevor zu lange vergangen war. Insbesondere war es <3 Sekunden, als ich den timeBefehl in Verbindung mit rm& verwendete cp. Ich ging hinein und untersuchte, Dest/ob es nicht existierte, aber siehe da, es war ganz und schien nicht betroffen zu sein. Dies ist ein bisschen überraschend, da A/ B/ C/sie recht klein waren. Möglicherweise 100–200 MB insgesamt. Dest/ist jedoch nur 1 TB schüchtern. Das Ausführen eines lson Dest / zeigte, dass sich an beiden Enden des Alphabets sowohl Dateien als auch Verzeichnisse befanden (z AFile.txt. B. .... .... Zoo.txt).

Habe ich Glück gehabt und das abgebrochen, rmbevor es auf meinem Dest / -Verzeichnis Chaos anrichtete? Ist das rmwirklich so langsam (zum Glück!)?

Wenn nicht, wie rmgehe ich vor, um Dinge rekursiv zu entfernen, sodass ich erraten kann, was möglicherweise verloren gegangen ist?

Ich erwarte nicht wirklich, dass ich das, was ich möglicherweise verloren habe, wiederfinden kann, sondern bin nur neugierig, was möglicherweise weggeblasen wurde.

N Klosterman
quelle

Antworten:

34

rm -rarbeitet nacheinander an jedem seiner Argumente. Wenn ein Argument ein Verzeichnis ist, listet es das Verzeichnis auf (mit den Funktionen opendirund readdiroder einer entsprechenden Methode) und bearbeitet nacheinander jeden Eintrag. Wenn es sich bei einem Eintrag um ein Verzeichnis handelt, wird dieser Eintrag rekursiv durchsucht.

Dies ist genau die gleiche Methode , dass andere Anwendungen rekursiv Traverse Verzeichnisse verwenden - find, ls -Rfusw.

Die Reihenfolge der Durchquerung ist unvorhersehbar. Auf den meisten Dateisystemen ist die Reihenfolge reproduzierbar, solange keine Datei im Verzeichnis hinzugefügt, entfernt oder umbenannt wird (die Reihenfolge kann theoretisch völlig zufällig sein und sich jedes Mal ändern, aber ich kann mir kein Dateisystem vorstellen, in dem dies geschieht). Bei einigen Dateisystemen kann die Reihenfolge im Allgemeinen anhand der Dateinamen oder anhand der Reihenfolge, in der die Dateien erstellt wurden, oder anhand einer Kombination aus beiden abgeleitet werden. Sie müssen jedoch die genauen Details des Dateisystems kennen, und diese können abhängig davon variieren die Treiberversion. Auf die Reihenfolge der Durchquerung können Sie sich nicht verlassen.

Beachten Sie, dass lsoder echo *sortieren Sie Dateien in der lexikografischen Reihenfolge ihrer Namen. findund ls -fnicht sortieren.

Sie können sich darauf verlassen, dass die Argumente in der richtigen Reihenfolge behandelt werden. Wenn C/es also noch teilweise da wäre, würde das bedeuten, dass Dest/es unberührt war. Wenn C/weg ist, können Sie eine Vorstellung davon bekommen, wo Dateien entfernt Dest/wurden, indem Sie die Verzeichnisänderungszeiten überprüfen und sie mit der Zeit vergleichen, zu der sie C/gelöscht wurden oder zu der die Kopie endete. Die erste zu löschende Datei kann eine Datei sein, die sich direkt Dest/oder tief in der Hierarchie befindet, je nachdem, ob der erste Eintrag in Dest/dieser Datei rmein Verzeichnis war oder nicht.

Die Geschwindigkeit von rmhängt hauptsächlich davon ab, wie viele Dateien gelöscht werden müssen. Es dauert eine sehr große Datei, um einen spürbaren Einfluss auf die Löschzeit zu haben. Der Großteil der Arbeit löscht nacheinander jeden Verzeichniseintrag. Die Daten der Datei werden nicht gelöscht. Zum Löschen des Inhalts einer Datei müssen nur die von ihr verwendeten Blöcke als frei markiert werden. Dies ist relativ schnell.

Gilles 'SO - hör auf böse zu sein'
quelle
2
Die -fOption von lswird als äquivalent zu dokumentiert -aU, wobei -abedeutet, dass alle Dateien -Uaufgelistet werden und bedeutet, dass sie nicht sortiert sind. Ich erinnere mich vage an die Begegnung mit einer Version von, lsin der -fes nicht funktioniert hat (ich glaube, es wurde als etwas anderes definiert), aber es hat -aUfunktioniert.
G-Man sagt, dass Monica
2
@ G-Man POSIX defined -f(als XSI-Erweiterung ); Es hat in der Tat andere Effekte als unsortiert. Es geht auf V7 zurück, so dass Sie nur schwerlich eine Implementierung ohne BusyBox finden können. -UNur unsortiert ist eine GNU-Funktion, ich glaube nicht, dass sie irgendwo anders existiert.
Gilles 'SO - hör auf böse zu sein'
@ Tim Nein. Sie können testen, indem Sie ls -Uin einem Verzeichnis ausführen . Dies ist die gleiche Reihenfolge, rm -rdie in diesem Verzeichnis funktionieren würde. Beachten Sie, dass das Hinzufügen oder Entfernen einer Datei die Reihenfolge der anderen Dateien ändern kann.
Gilles 'SO - hör auf böse zu sein'
Vielen Dank. (1) "Das Hinzufügen oder Entfernen einer Datei kann die Reihenfolge der anderen Dateien ändern." ls -UWenn Sie also versehentlich einen Teil der Dateien entfernen, können Sie dann nicht herausfinden, ob überlebende Verzeichnisse unberührt bleiben. (2) -U bedeutet "Listeneinträge in Verzeichnisreihenfolge". Bedeutet -U die Reihenfolge der Verzeichniseinträge im Verzeichnis?
Tim
5

Wie Gilles sagt, können Sie die Reihenfolge der Löschvorgänge in einem Verzeichnis nicht allgemein vorhersagen, sondern nur, dass die Verzeichnisse der obersten Ebene in der Reihenfolge auf der Befehlszeile verarbeitet werden.

Es wird jedoch auch garantiert, dass Verzeichnishierarchien von unten nach oben gelöscht werden, da Unix das Löschen von Verzeichnissen nur zulässt, wenn diese leer sind. Um ein Verzeichnis zu löschen, muss es zuerst alles darin entfernen. Wenn es Unterverzeichnisse enthält, muss es zuerst deren Inhalt entfernen und so weiter.

Barmar
quelle