uscire di trovare se un -exec fallisce


14

C'è un modo per scrivere un findcosì che si interrompe se una delle -execoperazioni fallisce su un file?

Ad esempio ( javacè convenientemente usato come programma che può restituire un codice di uscita 1 su alcuni file e per nessun altro motivo):

$ echo "public classXX A{}" >> A.java
$ echo "public class B{}" >> B.java
$ find . -iname \*.java -exec javac {} \;
./A.java:1: error: class, interface, or enum expected
public classXX A{}
       ^
1 error

Nell'esempio sopra, sebbene il execfile sul A.javanon sia riuscito (e abbia restituito un codice di uscita pari a 1), il findcomando è proseguito e ha anche compilato il file B.java. C'è un modo per uscire findo dovrei usare una qualche forma di forinvece?

La mia versione di find:

$ find -version  | head -1
find (GNU findutils) 4.4.2

Risposte:


5

Penso...

find ... -exec sh -c 'cmd "$0" || kill $PPID' \{\} \;

... dovrebbe fare il trucco per quasi tutti find.


Grazie @Gilles. Che cosa $0fa?
Mikeserv,

1
$0è il primo argomento di sh -c( $1è il secondo, ecc.) - convenzionalmente il nome del programma in esecuzione, ma qui stai eseguendo uno snippet e passando il nome del file che viene elaborato come $0ha un senso (ad esempio puoi vedere facilmente in ps). C'è una scuola di pensiero (a cui ovviamente non appartengo) che afferma che $0dovrebbe essere sempre eseguibile e dovresti scrivere sh -c 'cmd "$1" …' sh {}o qualcosa del genere.
Gilles 'SO- smetti di essere malvagio' il

@Gilles - piuttosto elegante. Molte grazie. L'ho capito in macchina mentre andavo all'asilo, ma ho dovuto pensarci per diversi minuti. È intelligente - lo userò. Ciò che effettivamente lo ha cliccato sopra per me è stata una modifica che mi sono ricordato di aver letto di Stephane su uno dei tuoi post in cui ha aggiunto un find-sh $0alla fine di una finddichiarazione. A mio avviso, questo sembra più utile, anche se immagino che sia quello che stai cercando a lungo termine che conta di più.
Mikeserv,

Non funziona per il caso sopra. Dopo che il find . -iname \*.java -exec sh -c 'javac "${0}" || kill '$$ {} \;file ha A.javaesito negativo e, comunque, viene compilato il file B.java.
Marco Giunio Bruto,

@MarcusJuniusBrutus - L'ho risolto. Avrei dovuto vedere il tuo commento prima. Ancora scusa.
Mikeserv,

4

Almeno con GNU findpuoi usare:

find ... -exec ... -o -quit

Mi sembra di avere difficoltà a chiarire dove si ferma il exec e inizia il -o. Entrambi find . -iname \*.java -exec javac {} -o -quit \;e find . -iname \*.java -exec javac {} \; -o -quit \;falliscono (in modi diversi)
Marcus Junius Brutus il

@MarcusJuniusBrutus \;è necessario al e di -exec(cioè prima -o -quitin questo caso) ma potrebbe non essere altrove.
Hauke ​​Laging,

2
L'uso -exec ... -o -quitnon funziona per me. Non elabora alcun file. Tuttavia questa linea funziona: find . -iname \*.java -not -exec javac '{}' \; -quit: -quitsi chiama, se -execè falso, vale a dire. ritorna con diverso da zero.
Savanto,

find . -iname \*.java -exec javac {} \; -o -quitinoltre, non è in grado di elaborare alcun file. Stranamente, find . -iname \* -exec echo 'foo' \; -o -quit lo fa "processo" i file.
Marcus Junius Brutus,

0

Consulta il tuo findmanuale. La risposta di @ Hauke ​​mi ha motivato a guardare e la ricerca di QNX ha -abortun'opzione che sembra simile -quitall'opzione GNU . Funziona per me purché io utilizzi \(e \)per raggruppare espressioni:

find . -mtime -4 -name <pattern> \( -exec my_cmd {} \; -o  -abort \) 

Nota: senza i parentesi, si interrompe sul primo file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.