xargsがエラーで終了しない

xargsがエラーで終了しない

find私はディレクトリに多くのファイルをインポートし、xargschroot環境で一度に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

ドキュメントxargsman 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' _ %

おすすめ記事