Quindi il seguente comportamento di unix find mi è costato caro:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
Come può aver senso questo?
Quindi il seguente comportamento di unix find mi è costato caro:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
Come può aver senso questo?
Risposte:
La riga di comando di find è composta da diversi tipi di opzioni, che sono combinate per formare espressioni.
L' find
opzione -delete
è un'azione.
Ciò significa che viene eseguito per ogni file abbinato finora.
Come prima opzione dopo i percorsi, tutti i file sono abbinati ... oops!
È pericoloso - ma la pagina man ha almeno un grosso avvertimento :
Da 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.
Da più avanti 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.
Nel provare cosa find
farà un comando:
Per vedere come piace un comando
find . -name '*ar' -delete
verrà eliminato, è possibile innanzitutto sostituire l'azione -delete
con un'azione più innocua, ad esempio -fls
o -print
:
find . -name '*ar' -print
Questo stamperà quali file sono interessati dall'azione.
In questo esempio, -print può essere lasciato fuori. In questo caso, non v'è l'azione a tutti, quindi si aggiunge la più ovvia implicitamente: -print
. (Vedi il secondo paragrafo della sezione "EXPRESSIONS" citata sopra)
-delete
bandiera :-) Ma c'è qualche motivo per cui qualcuno vorrebbe mai fare find . -delete
piuttosto che rm -rf .
? O capita che questo sia il modo in cui find
analizza ed elabora i suoi argomenti?
warning: use -depth when testing stuff you later want to -delete
cosa non hai fatto nel tuo esempio pratico di lato?
-n
un'opzione; Il primo comando non dovrebbe avere alcun uso pratico, ovviamente; Vado a cambiarlo.
Nell'ordine degli find
argomenti conta molto.
Gli argomenti possono essere opzioni, test e azioni. In genere è necessario utilizzare prima le opzioni, quindi i test, quindi le azioni.
A volte find
ti avverte persino di un possibile cattivo ordinamento (ad esempio quando usi -maxdepth
dopo altri argomenti), ma altri sembra che non lo faccia.
Quello che find . -delete -name '*ar'
fa è:
Quello che probabilmente vuoi fare è:
find -name '*ar' -delete
Questo, per ogni file, vedrà se corrisponde '*ar'
, e solo se soddisfa la condizione eliminerà il file.
Scusa se l'hai scoperto troppo tardi.