keluar dari find jika -exec gagal


14

Apakah ada cara untuk menulis findsehingga rusak jika salah satu -execoperasi gagal pada file?

Misalnya ( javacmudah digunakan sebagai program yang dapat mengembalikan kode keluar 1 pada beberapa file dan tanpa alasan lain):

$ 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

Dalam contoh di atas, walaupun execpada file A.javagagal (dan mengembalikan kode keluar 1), findperintah melanjutkan dan mengkompilasi file B.javajuga. Apakah ada cara untuk keluar findatau haruskah saya menggunakan beberapa bentuk for?

Versi penemuan saya:

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

Jawaban:


5

Kupikir...

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

... harus melakukan trik untuk apa saja find.


Terima kasih @Gilles. Apa yang $0dilakukan?
mikeserv

1
$0adalah argumen pertama untuk sh -c( $1adalah yang kedua, dll.) - secara konvensional nama program sedang dieksekusi, tetapi di sini Anda mengeksekusi cuplikan, dan meneruskan nama file yang sedang diproses $0masuk akal (misalnya, Anda dengan mudah melihat dalam ps). Ada aliran pemikiran (yang jelas bukan milik saya) yang menyatakan bahwa $0harus selalu dapat dieksekusi dan Anda harus menulis sh -c 'cmd "$1" …' sh {}atau semacamnya.
Gilles 'SO- stop being evil'

@Gilles - cukup apik. Terima kasih banyak. Saya menemukannya di mobil dalam perjalanan ke prasekolah, tetapi saya harus memikirkannya selama beberapa menit. Itu pintar - saya akan menggunakannya. Yang benar-benar mengkliknya untuk saya adalah suntingan yang saya ingat pernah membaca tulisan Stephane di salah satu pos Anda sendiri di mana dia menambahkan sebuah find-sh $0di akhir findpernyataan. Ini tampaknya lebih berguna menurut saya, meskipun saya kira itulah yang Anda cari dalam jangka panjang yang paling penting.
mikeserv

Ini tidak berfungsi untuk kasus di atas. Setelah find . -iname \*.java -exec sh -c 'javac "${0}" || kill '$$ {} \;file A.javagagal dan, masih, file B.java dikompilasi.
Marcus Junius Brutus

@MarcusJuniusBrutus - Saya memperbaikinya. Saya seharusnya melihat komentar Anda sebelumnya. Sekali lagi, maaf.
mikeserv

4

Setidaknya dengan GNU findAnda dapat menggunakan:

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

Saya sepertinya kesulitan menjelaskan di mana eksekutif berhenti dan -o dimulai. Keduanya find . -iname \*.java -exec javac {} -o -quit \;dan find . -iname \*.java -exec javac {} \; -o -quit \;gagal (dengan cara yang berbeda)
Marcus Junius Brutus

@MarcusJuniusBrutus \;diperlukan di and of -exec(yaitu sebelumnya -o -quitdalam kasus ini) tetapi mungkin tidak ada di tempat lain.
Hauke ​​Laging

2
Menggunakan -exec ... -o -quittidak berfungsi untuk saya. Itu tidak memproses file apa pun . Namun baris ini bekerja: find . -iname \*.java -not -exec javac '{}' \; -quit: -quitdisebut jika -execsalah, yaitu. kembali dengan nol.
savanto

find . -iname \*.java -exec javac {} \; -o -quitjuga gagal memproses file apa pun. Anehnya, find . -iname \* -exec echo 'foo' \; -o -quit apakah "proses" file.
Marcus Junius Brutus

0

Konsultasikan findmanual Anda . Jawaban Hauke ​​memotivasi saya untuk melihat dan menemukan QNX memiliki -abortopsi yang tampaknya mirip dengan -quitopsi GNU . Ini berfungsi untuk saya asalkan saya menggunakan \(dan \)untuk ekspresi grup:

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

Catatan: tanpa parens, itu dibatalkan pada file pertama.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.