これはの制限ですfind
。POSIX標準の戻りステータスがあることを指定しfind
たディレクトリを横断中にエラーが発生しない限り、0です。実行されたコマンドの戻りステータスは入力されません。
コマンドにステータスをファイルまたは記述子に書き込ませることができます。
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"
あなたが発見した別の方法は、xargsを使用することです。xargs
コマンドは、常にすべてのファイルを処理しますが、コマンドリターンゼロ以外のステータスのいずれかの場合は、ステータス1を返します。
find … -print0 | xargs -0 -n1 invalid_command
さらに別の方法はfind
、代わりにシェルで再帰的なグロビングを使用せずに使用**/
することです:サブディレクトリの深さを意味します。これには、バージョン4以上のbashが必要です。macOSはバージョン3.xでスタックしているため、ポートコレクションからインストールする必要があります。set -e
ゼロ以外のステータスを返す最初のコマンドでスクリプトを停止するために使用します。
shopt -s globstar
set -e
for x in **/*.xml; do invalid_command "$x"; done
bash 4.0から4.2では、これは機能しますが、ディレクトリへのシンボリックリンクを通過することに注意してください。これは通常望ましくありません。
bashの代わりにzshを使用する場合、再帰的なグロビングは箱から出してすぐに機能します。ZshはOSX / macOSでデフォルトで利用可能です。zshでは、次のように書くことができます
set -e
for x in **/*.xml; do invalid_command "$x"; done
xargs
アプローチは一般的には機能しbash -c
ますが、何らかの理由でコマンドが中断します。例:find . -name '*.xml' -print0 | xargs -0 -n 1 -I '{}' bash -c "foo {}"
。これは複数回find . -name '2*.xml' -print0 | xargs -0 -n 1 -I '{}' foo {}
実行されますが、一度実行されて失敗します。理由は何ですか?