Bashのスクリプト文の評価順序は何ですか?

Bashのスクリプト文の評価順序は何ですか?

左から右へ?あるいはその逆も?

例:

If [! -z "$ foo"] && [$ foo2 -eq 0]; then
    echo "something"
fi

どの評価を最初にすべきですか?

[! -z "$ foo"]

または

[$ foo2 -eq 0]

ありがとうございます!

答え1

シェルスクリプトでは、次のように言います。

if [ ! -z "$foo" ] && [ "$foo2" -eq 0 ]; then
    echo 'something'
fi

最初のテスト[ ! -z "$foo" ](可能な限り作成[ -n "$foo" ])が最初に実行されます。 2回目のテストはただ最初のテストが成功すると実行されます。もし両方テストが成功します。つまり、$foo値がnullではなく、$foo2算術値が0の場合にecho実行されます。

この&&演算子は、他の言語の同様の演算子のように動作します。シェルの実装段落評価&&左側が次の場合、右側のみが評価されます。本物

このif特定の文は、次のようにキーワードを使用せずに作成することもできますif

[ ! -z "$foo" ] && [ "$foo2" -eq 0 ] && echo 'something'

if ...; then ...; fiIMHOを使用する方が明確ですが。

繰り返しますが、これはecho次の場合にのみ実行されます。両方以前のテストは成功しました。

答え2

長すぎます。

で述べたようにすでに持っている答え、定義によるとリストを含めるシェルコマンド言語は、[ ! -z "$foo" ]最初に実行され、次に終了ステータス0を返す場合にのみ実行されます[ "$foo2" -eq 0 ]


Bashでは、コマンドの実行順序は「シェルコマンド」セクションで指定されています。バッシュリファレンスマニュアル。以下では、ここで提供された定義を(便宜上参照形式ではないが)そのまま再現できると仮定する。

Bashおよび他のPOSIX準拠シェルの場合、より正式な(しかしユーザーフレンドリーではない)定義は、「シェルコマンド言語」の章(具体的には「シェルコマンド」および「シェル構文」の段落)にあります。オープングループ基本仕様

コードから

if [ ! -z "$foo" ] && [ "$foo2" -eq 0 ]; then
    echo "something"
fi

私たちはif 複合コマンド、一つそしてリストそして三簡単なコマンド

条件付き構文の一般的な構文ifは次のとおりです。

if test-commands; then
    consequent-commands;
[elif more-test-commands; then
    more-consequents;]
[else alternate-consequents;]
fi

終了ステータスがtest-commands0の場合、consequent-commandsこの句が実行されます。

私たちtest-commandsの節はシーケンスであるANDのリストです。管路で区切ります&&

command1 && command2

command2where は、終了状態が 0 の場合にのみ実行されます。command1

AND リストは左の関連付けで実行されます。したがって:

command1 && command2 && command3

書かれているように実行します(括弧を擬似コードグループ化演算子として使用し、Bash言語で意味するものを少し忘れてください)。

(((command1) && command2) && command3)

ANDリストから

[ ! -z "$foo" ] && [ "$foo2" -eq 0 ]

最初のパイプライン

[ ! -z "$foo" ]

まず実行してください。 2番目のパイプラインが成功した場合にのみ

[ "$foo2" -eq 0 ]

処刑される。リストで最後に実行されたコマンドの終了ステータスが考慮されるステータスif

パイプは、制御演算子またはで|区切られた1つ以上のコマンドシーケンスです|&。両方のパイプラインは単なるコマンドです。

blanks単純なコマンドは、シェルの制御演算子の1つで区切られた一連の単語です。単純なコマンドは実行順序の問題を引き起こしません。

記録によると、ANDリストの単純なコマンドは、(組み込み)コマンドとそのコマンドの4つの[引数、、、、、、で構成されています。!-z"$foo"]"$foo2"-eq0]

最後に、consequent-commands複合コマンドの節はif単純なコマンドですecho "something"。つまり、実行順序の問題は発生しません。

関連情報