find
私はディレクトリに多くのファイルをインポートし、xargs
chroot環境で一度に1スクリプトの対応するファイルを実行するために使用するbashスクリプトを持っています。私の理解は、xargsがゼロ以外の終了コードをチェックすると終了して処理を停止しますが、何らかの理由でそうでないようです。
私が持っているスクリプトは次のとおりです。
#!/usr/bin/env bash
set -euo pipefail
script_dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )
rootfs="$1"
exec_script() {
script="$1"
relative_script_path="$(realpath --relative-to="$script_dir" "$script")"
echo -e "\e[1;94m=> executing script $script ($relative_script_path)\e[0m"
sleep 5
if ! "$rootfs/enter-chroot" sh -c "/$relative_script_path"; then
echo -e "\e[1;31m=> script $script failed\e[0m"
exit 1
fi
echo -e "\e[1;32m=> script $script ran successfully\e[0m"
}
export -f exec_script
export rootfs
export script_dir
find "$script_dir/build/scripts" -name '*.sh' -print0 | sort -z | xargs -r -0 -I% -n1 bash -c 'exec_script "$@"' _ %
実行すると、次の結果が表示されます。
./build/run.sh /tmp/test
=> executing script /tmp/builder/build/scripts/000-upgrade.sh (build/scripts/000-upgrade.sh)
environment: line 4: /tmp/test/enter-chroot: Not a directory
=> script /tmp/builder/build/scripts/000-upgrade.sh failed
=> executing script /tmp/builder/build/scripts/001-firmware.sh (build/scripts/001-firmware.sh)
environment: line 4: /tmp/test/enter-chroot: Not a directory
=> script /tmp/builder/build/scripts/001-firmware.sh failed
私はどこで間違っていますか? xargsが処理を停止し、ゼロ以外の終了コードで終了するようにするにはどうすればよいですか?
ベストアンサー1
ドキュメントxargs
(man xargs
実際に終了について話しているものを参照してください。
このコマンドの呼び出しが状態 255 で終了すると、追加の
xargs
入力を読み取ることなく即座に停止します。エラーメッセージは以下から送信されました。標準エラーこのようなことが起こった場合。
したがって、考えられる解決策の1つは、exec_script
エラーが発生したときに終了ステータス255を返すように変更することです。
何も変更できない場合、もう1つの可能な解決策exec_script
は一般的なコンテンツをxargs
シェルループに変換することです。
find "$script_dir/build/scripts" -name '*.sh' -print0 |
sort -z |
while IFS= read -r -d '' item && exec_script _ "$item"; do :; done
exec_script
ゼロ以外の終了値が返されると、ループは中断されます。
もう一つの解決策はコメントこれはおそらくスクリプトで終了エラーを見つけて255に置き換える最も簡単な外部修正です。
find "$script_dir/build/scripts" -name '*.sh' -print0 |
sort -z |
xargs -r -0 -I% -n1 bash -c 'exec_script "$@" || exit 255' _ %