Ini adalah batasan find
. Standar POSIX menentukan bahwa status pengembalian find
adalah 0 kecuali terjadi kesalahan saat melintasi direktori; status pengembalian dari perintah yang dieksekusi tidak masuk ke dalamnya.
Anda dapat membuat perintah menulis statusnya ke file atau ke deskriptor:
find_status_file=$(mktemp findstatus)
: >"$find_status_file"
find … -exec sh -c 'trap "echo \$?" EXIT; invalid_command "$0"' {} \;
if [ -s "$find_status_file" ]; then
echo 1>&2 "An error occurred"
fi
rm -f "$find_status_file"
Metode lain, seperti yang Anda temukan , adalah menggunakan xargs. The xargs
perintah selalu memproses semua file, tapi mengembalikan status 1 jika salah satu perintah pengembalian status nol.
find … -print0 | xargs -0 -n1 invalid_command
Namun metode lain adalah menghindari find
dan menggunakan globbing rekursif dalam shell sebagai gantinya: **/
berarti kedalaman subdirektori. Ini membutuhkan versi 4 atau lebih dari bash; macOS macet di versi 3.x sehingga Anda harus menginstalnya dari koleksi port. Gunakan set -e
untuk menghentikan skrip pada perintah pertama mengembalikan status bukan nol.
shopt -s globstar
set -e
for x in **/*.xml; do invalid_command "$x"; done
Berhati-hatilah bahwa dalam bash 4.0 hingga 4.2, ini berfungsi tetapi melintasi tautan simbolik ke direktori, yang biasanya tidak diinginkan.
Jika Anda menggunakan zsh sebagai ganti bash, globbing rekursif bekerja di luar kotak tanpa gotcha. Zsh tersedia secara default di OSX / macOS. Di zsh, Anda bisa menulis
set -e
for x in **/*.xml; do invalid_command "$x"; done
xargs
Pendekatan bekerja pada umumnya tapi entah bagaimana istirahat padabash -c
perintah. Sebagai contoh:find . -name '*.xml' -print0 | xargs -0 -n 1 -I '{}' bash -c "foo {}"
. Ini dieksekusi beberapa kali sedangkanfind . -name '2*.xml' -print0 | xargs -0 -n 1 -I '{}' foo {}
dieksekusi sekali dan gagal. Ada yang tahu kenapa?