Skip to main content

複数コマンド実行したときの return code とエラー処理とについて

前提

  • シェルスクリプトなどでエラー時は 非0 を返しておいて、後続の処理を停止する
  • これは慣習で、呼び出し元のコマンドなどはそのように書かれることが一般的

悩みごと

複数コマンドを呼んだときに、エラーだったら return、といった処理を書くのは、とても煩雑

bash
./command1.sh
r=$?
if [ $r -ne 0 ]; then
exit $r
fi

./command2.sh
r=$?
if [ $r -ne 0 ]; then
exit $r
fi

解決策1. set -e を使う方法

bash
set -e  # エラー発生時にスクリプトを即終了
set -o pipefail # パイプの場合出たエラーにも対応

./command1.sh
./command2.sh | sort
# ここまででエラーが発生すれば即終了します
  • エラーの場合に分岐して処理を書きたい、といったケースに不向きか
  • その場合は、$(...) のようにサブシェルで呼べば良いだけか

解決策2. && を使う方法

bash
./command1.sh \
&& ./command2.sh
  • ちょっと意図が分かりづらくなる可能性あり、か

解決策3. エラーハンドラを書く

bash
run_command() {
echo "Running: $@" # 実行するコマンドを表示
"$@" # 引数で渡されたコマンドを実行
r=$? # 実行結果をチェック
if [ $r -ne 0 ]; then
echo "Error: $1 failed with exit code $r"
exit $r
fi
}

# コマンドを呼び出す
run_command ./command1.sh
run_command ./command2.sh
  • これが一番まともっぽい
  • どのコマンドでエラーだったかを出せるのも良い。引数も出せればなお良いか