Sto cercando di eseguire più comandi su cose che ho trovato, come posso ottenere questo?
find . -exec cmd1; cmd2
non sembra funzionare; invece esegue cmd2 dopo che cmd1 è stato eseguito su ogni file.
Sto cercando di eseguire più comandi su cose che ho trovato, come posso ottenere questo?
find . -exec cmd1; cmd2
non sembra funzionare; invece esegue cmd2 dopo che cmd1 è stato eseguito su ogni file.
Risposte:
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. Quindi 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 \; \)
Nel secondo set, le parentesi di escape raggruppano le due -exec
clausole. Il rapporto -false
tra loro forza lo stato del test su "false" e -o
causa la -exec
valutazione dell'espressione successiva (la seconda ) a causa di -false
.
Da man find
:
expr1 expr2
Vengono prese due espressioni di seguito da unire con un "e" implicito; expr2 non viene valutato se expr1 è falso.expr1 -a expr2
Come per expr1 expr2.expr1 -o expr2
Oppure; expr2 non viene valutato se expr1 è true.
Se non ti interessa 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 far eseguire sempre entrambi i comandi è quello di avere find
invocato una shell che eseguirà successivamente i comandi in sequenza:
find . -exec bash -c 'cmd1; cmd2' filedumper {} \;
Se non ti dispiace creare uno script che esegua cmd1 e cmd2, allora è proprio questo:
find . -exec myscript {} \;
o
find . -exec myscript {} +
Uso \; o + a seconda che myscript sia in grado di gestire più di un file alla volta (diventa peloso se ci sono spazi nei nomi dei file, ecc.).
Inserire ciò che stavi facendo in una sceneggiatura, nella mia esperienza, è quasi sempre valsa la pena. Se devi farlo una volta, dovrai farlo di nuovo.
Ma un trucco accurato è quello di mettere la scoperta all'interno della sceneggiatura:
if [ $# -gt 0 ]; then
for each; do
touch $each
done
else
find . -exec $0 {} +
fi
Quindi myscript funziona su tutti i file che fornisci come argomenti su cui lavorare, ma se non gli dai alcun argomento, esegue find dalla directory corrente e quindi si chiama sui file trovati. Ciò aggira il fatto che find -exec non può chiamare le funzioni shell definite nello script.
Ho provato entrambe le soluzioni precedenti senza molta fortuna. Questo ha funzionato bene per me:
$ for i in `find . -exec echo {} \;`; do cmd1 $i; cmd2 $i; done
prova il comando:
sudo find -name "*[!0-9][1-9].txt" -exec chmod 744 * {} \; -a -exec ls -l {} \; | sort | parallel ls -l
*
nella -exec
parte si espanderà a tutti i file nella directory corrente. Soprattutto quando si esegue come sudo
.
-o
.