シェル スクリプトの条件が期待どおりに動作しない

シェル スクリプトの条件が期待どおりに動作しない

Linux コマンドをいくつか実行し、if 句で例外をキャプチャして結果を出力するスクリプトを作成しました。基本的に、以下のコード抜粋の各変数はコマンド実行ステータスを表し、すべてのコマンドが正常に実行された場合にスクリプトを正常に終了したいと考えています。それ以外の場合は、1 つのコマンドで終了したいと考えています。スクリプトをテストしているときに、意図的にコマンドを失敗させ、たとえば X8 の 1 つの変数の出力が 1 になるようにしました。このシナリオでは、以下は期待どおりに動作しません。スクリプトが失敗したメッセージではなく、成功メッセージが表示されます。理由はわかりません。

if [ $X1 != 0 ] &&  [ $X2 != 0 ] &&  [ $X3 != 0 ] && [ $X4 != 0 ] && [ $X5 != 0 ] && [ $X6 != 0 ] && [ $X7 != 0 ] && [ $X8 != 0 ];
then echo "script failed"; exit 1;     
else echo "success"; fi;

答え1

スクリプトの先頭に以下を追加します:

trap 'echo "Error $? at $LINENO; aborting." 1>&2; exit $?' ERR

その後、キャッチされないエラーが発生するたびに、スクリプトは上記のメッセージで終了し、エラーの終了コードで終了します。すべてのエラーに対して終了コード 1 を使用したい場合は、$?に変更できます。1

答え2

まず、 の省略形である を使用してい[ますtestman test

  STRING1 != STRING2
         the strings are not equal

あなたは間違ったツールを使っています。必要なのは

 INTEGER1 -eq INTEGER2
         INTEGER1 is equal to INTEGER2

2 番目に、ここでは複数の条件をテストする必要があります。1 つの長い if ステートメントを使用する代わりに、glenn がコメントで提案したように、各変数の出力を合計してテストしてください。または、各コマンドの出力を、その直後に評価します。そのコマンドの出力が原因で終了する場合は、他のコマンドを実行しても意味がありません。

ループアプローチは次のとおりです。

for i in $X1 $X2 $X3 ; 
do 
    [ $i -ne 0 ] && { echo "something failed"; exit 1; }
done
echo "Everything OK"

ここでの秘訣は、変数のそれぞれに対して同じテストを実行することです。そのテストが失敗すると、スクリプトは「すべてOK」の部分に到達しません。

関連情報