Verwenden von `find` zum Löschen

7

Also, bei drei Optionen ...

  1. find .... -delete
  2. find .... | xargs rm ...
  3. find .... -exec rm ...;

..oder Variationen davon, welche Option ist vorzuziehen?
Ich vermute, es gibt keine feste Antwort, und eine bestimmte Situation wird die beste Option bestimmen (bitte nennen Sie sie!).

Prost.

Ben Davies
quelle
1
Sie haben eines vergessen: Das find ... -exec rm ...+ist ähnlich schnell wie die xargsVersion.
Bis auf weiteres angehalten.
Seien Sie vorsichtig, einige von ihnen haben ein anderes Verhalten. Wenn der Pfad beispielsweise ein Leerzeichen enthält, interpretiert die zweite Option mit xargs den Pfad als mehrere Dateien und löst Fehler aus (und verursacht andere Probleme).
paulusdd

Antworten:

15

Option 1 vermeidet das Laichen externer Prozesse, was unter Stressbedingungen nützlich ist.

Option 2 erzeugt einen einzelnen xargsProzess, der nur so viele rmProzesse wie nötig erzeugt. Diese Option wird normalerweise mit -print0und -0verwendet, um Dateinamen mit Leerzeichen und / oder Zeilenumbrüchen zu behandeln.

Option 3 erzeugt einen rmProzess für jede Datei.

GNU find (oder eine POSIX-kompatible Version von find) ermöglicht eine vierte Option, find .... -exec rm -r {} +die rmmit so vielen Dateinamen wie möglich ausgeführt wird, um nur eine begrenzte Anzahl von ihnen zu erzeugen.

Ignacio Vazquez-Abrams
quelle
In der Praxis verwende ich immer nur die xargs-Methode.
Brian Knoblauch
5

Ich bevorzuge es, find ... > file.txtdie Datei ausgiebig zu überprüfen und dann zu verwenden, find ... -deletedamit ich weiß, dass genau die gleichen Ergebnisse gelöscht werden (das Übergeben von Argumenten ist meistens kugelsicher, meistens).

Chris S.
quelle
Wenn Sie diesen Ansatz wählen, achten Sie auf die Rennbedingungen. Das heißt, die Möglichkeit, dass sich der Inhalt des Dateisystems zwischen den beiden Befehlen ändert. Auch die Tatsache, dass in der ersten Befehlszeile die Option -depth nicht wirksam ist, während sie sich in der zweiten befindet (da dies implizit durch -delete verursacht wird).
James Youngman
2

Das Thema Löschen von Dateien wird im Abschnitt "Aufräumen" in der Dokumentation zu GNU findutils behandelt. Sie können dies auf Ihrem System mit "info find" oder in Emacs lesen. Sie können es auch online unter http://www.gnu.org/software/findutils/manual/html_node/find_html/Cleaning-Up.html#Cleaning-Up anzeigen .

find .... -delete

Dies ist die sicherste (gegen symbolische Link-Rennen) und leistungsstärkste (da bei vollem Pipe-Puffer nichts ausgeführt oder ein Kontextwechsel durchgeführt werden muss) Option. Aber denken Sie daran, dass -delete -tiefe impliziert.

find .... | xargs rm ...

Dies ist in Situationen gefährlich, in denen andere Schreibzugriff auf den Baum haben, in dem Sie bereinigen. Angenommen, der Befehl find hat entschieden, dass /var/tmp/scratch/me/.ssh/config den Anforderungen entspricht, und druckt daher diese Namen zu stdout. Der Befehl xargs liest das und fügt es einer Datenstruktur hinzu. Kurze Zeit später (wenn xargs die durch den Standardwert der Option -s angegebene Anzahl von Bytes gelesen hat) wird xargs gegabelt und ausgeführt, um sie zu löschen. Es ist jedoch möglich, dass in der Zwischenzeit jemand anderes dies getan hat:

$ cd /var/tmp/scratch
$ mv me me.old
$ ln -s /root me

Wenn rm dann /var/tmp/scratch/me/.ssh/config löscht, wird der Systemaufruf unlink ("/ var / tmp / kratzer / me / .ssh / config") ausgegeben. Da der Kernel die symbolische Verknüpfung für Sie auflöst, entspricht dies dem Aufruf von unlink ("/ root / .ssh / config"). Wenn der xargs-Prozess als root ausgeführt wurde, wird /root/.ssh/config gelöscht, obwohl Sie in der Befehlszeile -L nicht angegeben haben. Wenn Sicherheit wichtig ist, verwenden Sie aus diesem Grund -delete. Weitere Informationen zu diesem Bereich finden Sie im Abschnitt "Sicherheitsaspekte" des GNU-Suchhandbuchs.

find .... -exec rm ...;

Da dies auch Fork / Exec betrifft, gibt es dieselben Sicherheitsprobleme, die ich oben erwähnt habe.

Kurz gesagt, der einzige Grund, -delete nicht zu verwenden, ist die Kompatibilität mit Systemen, die -delete nicht unterstützen.

James Youngman
quelle