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' findopzione -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 findfarà un comando:
Per vedere come piace un comando
find . -name '*ar' -delete
verrà eliminato, è possibile innanzitutto sostituire l'azione -deletecon un'azione più innocua, ad esempio -flso -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)
-deletebandiera :-) Ma c'è qualche motivo per cui qualcuno vorrebbe mai fare find . -deletepiuttosto che rm -rf .? O capita che questo sia il modo in cui findanalizza ed elabora i suoi argomenti?
warning: use -depth when testing stuff you later want to -deletecosa non hai fatto nel tuo esempio pratico di lato?
-nun'opzione; Il primo comando non dovrebbe avere alcun uso pratico, ovviamente; Vado a cambiarlo.
Nell'ordine degli findargomenti 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 findti avverte persino di un possibile cattivo ordinamento (ad esempio quando usi -maxdepthdopo 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.