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

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

Gibt es eine bestimmte Reihenfolge für die Vorgänge rm? Ich habe dies rmin einem großen Verzeichnis durchgeführt und bin neugierig, wo ich nachsehen muss, was möglicherweise gelöscht wurde. Funktioniert dies rmzuerst in Dateien und dann in Verzeichnissen? Oder basiert es auf Informationen in der Inode-Tabelle?

Spezifikationen: rm vom GNU Coreutils 8.22-System: Arch Linux läuft auf einem Beagleboneblack-Dateisystem, das auf einer externen Seagate-Festplatte (ext4) mit USB 2.0 läuft.

Hintergrundgeschichte:

Ich habe einige Verzeichnisbereinigungen durchgeführt und

cp -r A/ B/ C/ Dest/

Unwissentlich folgte mir

rm -r A/ B/ C/ Dest/

als ich einfach nur auftreten wollte

rm -r A/ B/ C/

CtrlIch habe das bemerkt und + gedrückt, Cbevor zu viel Zeit vergangen war. Genauer gesagt waren es < 3 Sekunden, da ich den timeBefehl in Verbindung mit rm& verwendet habe cp. Ich ging hinein und untersuchte es und Dest/erwartete, dass es nicht existierte, aber siehe da, es war ganz underschiennicht betroffen zu sein. Das ist etwas überraschend, da A/ B/ C/sie ziemlich klein waren. Vielleicht 100–200 MB insgesamt. Das Dest/ist jedoch knapp unter 1 TB. Das Ausführen eines lsauf Dest/ zeigte, dass es sowohl Dateien als auch Verzeichnisse an beiden Enden des Alphabets gab (z. B. AFile.txt.... .... Zoo.txt).

Hatte ich Glück und habe es abgebrochen, rmbevor es Chaos in meinem Dest/-Verzeichnis angerichtet hat? Ist es rmwirklich so langsam (zum Glück!)?

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

Ich erwarte nicht wirklich, dass ich das zurückbekomme, was ich möglicherweise verloren habe, bin nur neugierig, was möglicherweise weggeblasen wurde.

Antwort1

rm -rbearbeitet nacheinander alle seine Argumente. Wenn ein Argument ein Verzeichnis ist, listet es das Verzeichnis auf (mit demopendirUndreaddirFunktionen oder eine gleichwertige Methode) und bearbeitet nacheinander jeden Eintrag. Wenn es sich bei einem Eintrag um ein Verzeichnis handelt, wird dieser Eintrag rekursiv untersucht.

Dies ist genau die gleiche Methode, die andere Anwendungen verwenden, um Verzeichnisse rekursiv zu durchlaufen – find, ls -Rf, usw.

Die Reihenfolge der Durchquerung ist unvorhersehbar. Bei den meisten Dateisystemen ist die Reihenfolge reproduzierbar, solange keine Datei im Verzeichnis hinzugefügt, entfernt oder umbenannt wird (die Reihenfolge könnte theoretisch völlig zufällig sein und sich jedes Mal ändern, aber mir fällt kein Dateisystem ein, bei dem das passiert). Bei einigen Dateisystemen kann die Reihenfolge im Allgemeinen aus den Dateinamen oder aus der Reihenfolge, in der die Dateien erstellt wurden, oder aus einer Kombination aus beidem abgeleitet werden, aber Sie müssen die Feinheiten des Dateisystems kennen, und sie könnte je nach Treiberversion variieren. Die Reihenfolge der Durchquerung ist nichts, worauf Sie sich verlassen können.

Beachten Sie, dass die Dateien lsentweder echo *in der lexikografischen Reihenfolge ihrer Namen sortiert werden findoder ls -fnicht sortiert werden.

Sie können sich darauf verlassen, dass die Argumente der Reihe nach behandelt werden. Wenn also C/noch teilweise vorhanden war, bedeutet dies, dass es Dest/unberührt war. Wenn C/nicht vorhanden ist, können Sie sich einen Eindruck davon verschaffen, wo Dateien entfernt wurden, Dest/indem Sie die Änderungszeiten des Verzeichnisses prüfen und sie mit der Zeit vergleichen, zu der C/es gelöscht wurde oder zu der das Kopieren beendet wurde. Die erste zu löschende Datei könnte eine Datei direkt in Dest/oder irgendwo tief in der Hierarchie sein, je nachdem, ob der erste Eintrag, Dest/der rmzufällig durchlaufen wurde, ein Verzeichnis war oder nicht.

Die Geschwindigkeit rmhängt hauptsächlich davon ab, wie viele Dateien gelöscht werden müssen. Es muss sich um eine sehr große Datei handeln, um die Löschzeit spürbar zu verkürzen. Der Großteil der Arbeit besteht darin, jeden Verzeichniseintrag einzeln zu löschen. 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, was relativ schnell geht.

Antwort2

Wie Gilles sagt, lässt sich die Reihenfolge der Löschungen innerhalb eines Verzeichnisses im Allgemeinen nicht vorhersagen, sondern nur, dass die Verzeichnisse der obersten Ebene in der Reihenfolge verarbeitet werden, in der sie auf der Befehlszeile angegeben sind.

Allerdings ist auch gewährleistet, dass Verzeichnishierarchien von unten nach oben gelöscht werden, da Unix das Löschen von Verzeichnissen nur zulässt, wenn sie leer sind. Um also 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.

verwandte Informationen