Also das folgende Verhalten von Unix kostet mich nur teuer:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
Wie macht das Sinn?
Also das folgende Verhalten von Unix kostet mich nur teuer:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
Wie macht das Sinn?
Antworten:
Die Befehlszeile von find besteht aus verschiedenen Arten von Optionen, die zu Ausdrücken kombiniert werden.
Die find
Option -delete
ist eine Aktion.
Das heißt, es wird für jede Datei ausgeführt, die bisher abgeglichen wurde.
Als erste Option nach den Pfaden werden alle Dateien abgeglichen ... Hoppla!
Es ist gefährlich - aber die Manpage hat zumindest eine große Warnung :
Von man find
:
ACTIONS
-delete
Delete files; true if removal succeeded. If the removal failed, an
error message is issued. If -delete fails, find's exit status will
be nonzero (when it eventually exits). Use of -delete automatically
turns on the -depth option.
Warnings: Don't forget that the find command line is evaluated as an
expression, so putting -delete first will make find try to delete
everything below the starting points you specified. When testing a
find command line that you later intend to use with -delete, you
should explicitly specify -depth in order to avoid later surprises.
Because -delete implies -depth, you cannot usefully use -prune and
-delete together.
Von weiter oben in man find
:
EXPRESSIONS
The expression is made up of options (which affect overall operation rather
than the processing of a specific file, and always return true), tests
(which return a true or false value), and actions (which have side effects
and return a true or false value), all separated by operators. -and is
assumed where the operator is omitted.
If the expression contains no actions other than -prune, -print is per‐
formed on all files for which the expression is true.
Beim Ausprobieren, was ein find
Befehl bewirkt:
Um zu sehen, wie ein Befehl aussieht
find . -name '*ar' -delete
löschen, können Sie die Aktion zuerst -delete
durch eine harmlosere Aktion ersetzen - wie -fls
oder -print
:
find . -name '*ar' -print
Dadurch wird gedruckt, welche Dateien von der Aktion betroffen sind.
In diesem Beispiel kann der -print weggelassen werden. In diesem Fall gibt es keine Maßnahmen überhaupt, so die naheliegendste implizit hinzugefügt wird: -print
. (Siehe den zweiten Absatz des oben genannten Abschnitts "AUSDRÜCKE")
-delete
Flagge hinzuzufügen :-) Aber gibt es einen Grund, den irgendjemand jemals find . -delete
lieber tun würde als rm -rf .
? Oder ist das nur die Art find
und Weise, wie Argumente analysiert und verarbeitet werden?
warning: use -depth when testing stuff you later want to -delete
was Sie in Ihrem praktischen Beispiel nicht getan haben?
-n
Option veranschaulichen ; Der erste Befehl sollte natürlich überhaupt keinen praktischen Nutzen haben; Ich werde es ändern gehen.
In der find
Argumentationsreihenfolge zählt viel.
Argumente können Optionen, Tests und Aktionen sein. In der Regel sollten Sie zuerst Optionen, dann Tests und dann Aktionen verwenden.
Manchmal werden Sie find
sogar vor einer möglichen Fehlbestellung gewarnt (zum Beispiel, wenn Sie -maxdepth
nach anderen Argumenten suchen), bei anderen scheint dies jedoch nicht der Fall zu sein.
Was find . -delete -name '*ar'
macht ist:
Was Sie wahrscheinlich tun möchten, ist:
find -name '*ar' -delete
Dadurch wird für jede Datei geprüft, ob sie übereinstimmt '*ar'
, und nur, wenn die Bedingung erfüllt ist, wird die Datei gelöscht.
Entschuldigung, wenn Sie es zu spät herausgefunden haben.