find - exec rm vs -delete


260

Ich versuche den Unterschied zwischen diesen beiden Befehlen zu verstehen:

sudo find / -name .DS_Store -delete

und

sudo find / -name ".DS_Store"  -exec rm {} \;

Mir ist aufgefallen, dass die execMethode bevorzugt wird. Warum? Welches ist sicherer / schneller / besser? Ich habe beide auf meinem Macbook verwendet und alles scheint gut zu funktionieren.

Antworten:


245

-delete wird eine bessere Leistung erbringen, da nicht für jede übereinstimmende Datei ein externer Prozess erzeugt werden muss.

Es ist möglich, dass Sie -exec rm {} \;häufig empfohlen sehen, da -deletenicht in allen Versionen von find. Ich kann jetzt nicht nachsehen, aber ich bin mir ziemlich sicher, dass ich eine findohne verwendet habe.

Beide Methoden sollten "sicher" sein.

EDIT pro Kommentar von @doitmyway: stellen Sie sicher , auf dem Namen übereinstimmen und dann löschen, nicht umgekehrt ( löschen, dann passen). Andernfalls wird jede Datei gelöscht, unabhängig davon, ob sie übereinstimmt oder nicht . Dh, NICHT tun: find / -delete -name .DS_Store.

Eine gebräuchliche Methode, um den Overhead des Ablegens eines externen Prozesses für jede übereinstimmende Datei zu vermeiden, ist:

find / -name .DS_Store -print0 | xargs -0 rm

(Beachten Sie jedoch, dass es auch hier ein Portabilitätsproblem gibt: Nicht alle Versionen von find haben -print0!)


2
Aha. Ich habe auch gelesen, dass das Verwenden des -deleteSchalters vor dem -nameLöschen des angegebenen Dateibaums, also denke ich, dass ich vorsichtig sein muss.
Zwiebel

8
In letzter Zeit können findSie -exec rm {} +alle übereinstimmenden Dateien mit einem einzigen rmBefehl entfernen .
Jimmy

3
.DS_Storeenthält überhaupt keine Sonderzeichen, daher sind die Anführungszeichen unnötig und ändern in diesem Fall nichts.
Celada,

1
Grundsätzlich ist nur ein Leerzeichen (Leerzeichen, Tabulatoren, möglicherweise andere) das einzige, was dazu führt, dass eine nicht in Anführungszeichen gesetzte Zeichenfolge als zwei separate Befehlszeilenargumente interpretiert wird. Dies ist jedoch nicht alles, was Sie bei der Entscheidung über ein Anführungszeichen bedauern müssen. Sie müssen sich um alle Shell-Metazeichen wie ;oder |oder >oder <und `` und viele andere kümmern, die für die Shell eine besondere Bedeutung haben, sofern nicht anders angegeben.
Celada

1
@MarcoMarsala xargskümmert sich transparent um das Problem der begrenzten Argumentliste, indem es es in mehrere Aufrufe des Befehls aufteilt .
Celada

27

Unter .DS_Storeder Annahme , dass Dateien und nicht Verzeichnisse dargestellt werden, ist der schnellste Weg dies zu tun:

sudo find / -name .DS_Store -exec rm {} +

Das einzige Risiko besteht darin, sudonicht verfügbar zu sein, aber es ist heutzutage recht gering.

Die -deleteOption, die verwendet wird, um GNU find anzufordern, ist in vielen anderen findImplementierungen immer noch nicht Standard und daher nicht immer verfügbar.

Der Befehl Beendigung +statt \;hoch optimiert die execKlausel nicht den laufenden rmBefehl für jede , .DS_Storedie auf dem Dateisystem.


16

Bei einer Maschine wie Ihrem MacBook werden Sie keinen großen Leistungsunterschied zwischen den beiden Befehlen feststellen. Wenn Sie sich jedoch die -exec-Version ansehen, können Sie einen subtilen Unterschied feststellen:

sudo find / -iname ".file-to-delete"  -exec rm {} \;

Das bedeutet, dass Sie alle Dateien mit dem Namen ".file-to-delete" finden. Diese Suche kann jedoch einige unerwünschte Fehlalarme zurückgeben. Wenn Sie etwas mit sudo machen, sollten Sie etwas vorsichtiger sein. Der Vorteil von -exec rm {} ist, dass Sie Argumente wie folgt an rm übergeben können:

sudo find / -iname "*~"  -exec rm -i {} \;

In diesem Beispiel möchte ich die Sicherungsdateien entfernen, die Emacs erstellt. Diese Tilde könnte sich jedoch in einer undurchsichtigen Datei befinden, von der ich nichts weiß und die wichtig sein könnte. Außerdem möchte ich das Löschen bestätigen. Also habe ich dem Befehl rm die Option '-i' hinzugefügt. Dies gibt mir ein interaktives Löschen.

Sie können auch die Verwendung von rm verfeinern, um Verzeichnisse und Dateien zu löschen:

find /usr/local/share/ -iname "useless" -exec rm -r {} \;

Kurz gesagt, mit -exec haben Sie etwas mehr Kontrolle über den tatsächlichen Befehl, mit dem das gefundene Element entfernt wird. Der Vorteil ist, dass Sie ein Tool verwenden, um die Dateien zu finden, und ein anderes Tool, um sie zu entfernen. Auch hat nicht jede Version des Dienstprogramms find die Option -delete. Verwenden Sie also besser jedes Werkzeug für die richtige Arbeit. Dies ist die Unix-Philosophie - ein Tool, ein Job, verwenden Sie sie zusammen, um das zu tun, was Sie tun müssen.


3
Siehe auch -ok rm {} \;anstelle von -exec rm {} \;für eine interaktive Bestätigung.
Kusalananda
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.