In questa dimostrazione, userò sh -c 'echo first; false'
(o true
) per il primo -exec
. Ciò fornirà un output e avrà anche l'effetto del codice di uscita selezionato. Poi echo second
verrà utilizzato per il secondo. Supponiamo che ci sia un file nella directory corrente.
$ find . -type f -exec sh -c 'echo first; false' \; -exec echo second \;
first
$ find . -type f -exec sh -c 'echo first; true' \; -exec echo second \;
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
$ find . -type f \( -exec sh -c 'echo first; false' \; -false -o -exec echo second \; \)
first
second
Un vero comando di questo tipo sarebbe simile a:
find . -type f \( -exec command1 \; -false -o -exec command2 \; \)
Nella seconda serie, le parentesi con escape raggruppano i due -exec
clausole. Il -false
tra di loro forza lo stato del test su "false" e il -o
causa l'espressione successiva (la seconda -exec
) da valutare a causa del -false
.
Da man find
:
espr1 espr2
Due espressioni di fila sono prese per essere unite con un "e" implicito; expr2 non viene valutato se expr1 è false.espr1 -a espr2
Uguale a expr1 expr2.espr1 -o espr2
O; expr2 non viene valutato se expr1 è true.
Se non ti importa che cmd1 sia in grado di impedire l'esecuzione di cmd2 a causa del codice di errore 0
:
find . -exec cmd1 \; -exec cmd2 \;
L'unico modo affidabile per fare in modo che entrambi i comandi lo eseguano sempre è avere find
richiamare una shell che successivamente eseguirà i comandi in sequenza:
find . -exec bash -c 'cmd1; cmd2' filedumper {} \;
Se non ti dispiace creare uno script che esegua cmd1 e cmd2, allora è solo questo:
find . -exec myscript {} \;
o
find . -exec myscript {} +
Uso \; o + a seconda che myscript possa gestire più di un file alla volta (diventa peloso se ci sono spazi nei nomi dei file, ecc.).
Mettere quello che stavi facendo in una sceneggiatura, nella mia esperienza, ne è valsa quasi sempre la pena. Se devi farlo una volta, dovrai farlo di nuovo.
Ma un bel trucco è inserire la ricerca all'interno lo script:
if [ $# -gt 0 ]; then
for each; do
touch $each
done
else
find . -exec $0 {} +
fi
Quindi myscript funziona su qualsiasi file gli fornisci come argomento su cui lavorare, ma se non gli dai alcun argomento, esegue find dalla directory corrente e quindi chiama se stesso sui file trovati. Questo aggira il fatto che find -exec non può chiamare le funzioni della shell che hai definito nel tuo script.