Gibt es eine bestimmte Reihenfolge für die Vorgänge rm
? Ich habe dies rm
in einem großen Verzeichnis durchgeführt und bin neugierig, wo ich nachsehen muss, was möglicherweise gelöscht wurde. Funktioniert dies rm
zuerst 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 time
Befehl 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 ls
auf 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, rm
bevor es Chaos in meinem Dest/-Verzeichnis angerichtet hat? Ist es rm
wirklich so langsam (zum Glück!)?
Wenn nicht, wie gehe ich rm
vor, 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 -r
bearbeitet nacheinander alle seine Argumente. Wenn ein Argument ein Verzeichnis ist, listet es das Verzeichnis auf (mit demopendir
Undreaddir
Funktionen 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 ls
entweder echo *
in der lexikografischen Reihenfolge ihrer Namen sortiert werden find
oder ls -f
nicht 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 rm
zufällig durchlaufen wurde, ein Verzeichnis war oder nicht.
Die Geschwindigkeit rm
hä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.