Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2866

Bashで終了ステータスごとに異なる処理を行いたい場合にハマった

$
0
0
複数パターンの終了ステータスを返す「とあるスクリプト」を作成 終了ステータスが成功パターン(exit 0)、失敗パターンA(exit 1)、失敗パターンB(exit 2)のように3パターンにわかれる「とあるスクリプト」を作成しました。(元々のスクリプトはもっと複雑なんですが、ここでは簡略化して書いてます) とあるスクリプト.sh 処理A || { # 失敗パターンA exit 1 } 処理B || { # 失敗パターンB exit 2 } # 成功パターン exit 0 「とあるスクリプト」の終了ステータスを判定して、それぞれ異なる処理を行うスクリプトを作成 「とあるスクリプト」を「呼び出す側のスクリプト」で、終了ステータスごとに異なる処理を行おうと思い、以下のような条件分岐を書きました。 元々は成功パターンと失敗パターンAの2パターンだけだったんですが、失敗パターンBが登場して3パターンとなり、以下のような分岐にしてみたという経緯があります。 呼び出す側のスクリプト.sh bash とあるスクリプト.sh if [ $? -eq 0 ] ; then echo '成功パターンの場合の処理' elif [ $? -eq 1 ] ; then echo '失敗パターンAの場合の処理' elif [ $? -eq 2 ] ; then echo '失敗パターンBの場合の処理' fi 想定外の結果に すると、 exit 1 と exit 2 のどちらの場合も「失敗パターンAの場合の処理」と出力されてしまいました。 パッと見は間違ってなさそうに見えるんですが、どうにもうまくいきません。なぜでしょう? 問題の原因 「とあるスクリプト」の実行後に if [ $? -eq 0 ] ; then の部分で  [ $? -eq 0 ] というコマンドが実行されます。 失敗パターンB(exit 2)の場合は [ 2 -eq 0 ] なので、判定は偽となり終了ステータスが 1 となります。 $? は「直前に実行した処理」の終了ステータスが格納される変数なので、 bash とあるスクリプト.sh を実行した際は $? に 2 がセットされていますが、 [ $? -eq 0 ] が実行されることにより $? が 1 に変わるわけです。 これにより、失敗パターンBの場合、 elif [ $? -eq 1 ] ; then の部分で [ $? -eq 1 ] というコマンドは [ 1 -eq 1 ] になってしまうので、判定は真となり「失敗パターンAの場合の処理」と出力されていたワケです。 解決方法 この問題を解決するにはどうしたらよいのでしょう? $? が上書きされてしまうことが問題なので bash とあるスクリプト.sh を実行した直後に終了ステータスを変数にセットすることで解決します。 呼び出す側のスクリプト.sh bash とあるスクリプト.sh result=$? if [ $result -eq 0 ] ; then echo '成功パターンの場合の処理' elif [ $result -eq 1 ] ; then echo '失敗パターンAの場合の処理' elif [ $result -eq 2 ] ; then echo '失敗パターンBの場合の処理' fi 終了ステータスが2パターンから3パターンに増えて、これからも増えるかもしれないことを考慮すると、 elif をたくさん並べるよりも case に書き換えるというのもアリかもしれませんね。 呼び出す側のスクリプト.sh bash とあるスクリプト.sh result=$? case $result in 0 ) echo '成功パターンの処理' ;; 1 ) echo '失敗パターンAの処理' ;; 2 ) echo '失敗パターンBの処理' ;; esac おまけ ちょっと前に、「シェルスクリプトの「if」は条件式の「コマンド」の実行結果を判定している」という記事を書いてまして、 if の仕組みは理解していたつもりだったのにハマってしまいました。。。 参考URL Man page of TEST if 文と test コマンド Bashで終了ステータスよる条件分岐

Viewing all articles
Browse latest Browse all 2866

Trending Articles