bashは次のコードをどのように評価するか

bashは次のコードをどのように評価するか

この質問には 2 つの部分があります。

(a) 切り取ったコードが何をしているのかを理解する

(b)違いを理解する終了ステータスそして返品ステータスの文脈でbash

私が理解しようとしているコードの抜粋は次のとおりです:

if var=-2 && (( var+=2 ))
then
    echo "True"
else
    echo "False"
fi

これを実行すると が生成されますFalse。なぜこのようなことが起こるのか理解できません。

私がこれを正しく理解していれば、このif状態で何が起きているのかは次のようになります:

(a)var=-2代入が成功したため、終了ステータス0が生成される。

(b)(( var+=2 ))は の値に 2 を加えvar、式はゼロと評価されます。したがって、この項の終了ステータスは 1 です。

(c) 0 && 1は0の存在ステータスを作成し、それがifコンストラクトによって使用される。

このif構造は単に終了ステータスをチェックし、それがゼロの場合はそれからパス。上記のステップ(c)ではゼロですが、スクリプトはそれ以外パス。これは正しい理解方法でしょうか?

bashまた、さまざまなテキストで使用されているのを見ます終了ステータスそして返品ステータス互換的に。

var=-2代入はプログラムではないので、何らかの終了ステータスがあるかどうかは疑問です。しかし、2 つの違いについての説明があれば助かります。

答え1

それは:

if
  first list of commands
then
  second list of commands
else
  third list of commands
fi

これは、最初のコマンドリストが次の結果を返す場合に、2番目のコマンドリストを実行するというものです。真実/成功(ゼロ) 終了ステータス、つまり、最後の実行コマンドがゼロの終了ステータスを返す場合です。

で:

var=-2 && ((var += 2))

成功した場合にのみ実行されるcmd1 && cmd2場所です。cmd2cmd1

var=-2

$var読み取り専用になっていない限り、通常は成功します。そのため、次の((var += 2))コマンドが実行されます。

((arithmetic expression))

戻り値成功/真実式が正しく評価され(構文エラーがなく)、式の結果がゼロ以外である限り。

  • ((123))、、trueを((1 + 1))返す((1 == 1))
  • ((0))、、 false((-2 + 2))((2 == -2))返します。
  • ((4294967296 * 4294967296))64ビット整数のラッピングのため、ほとんどのシェルではfalseを返します。

var += 2算術式として、代入を実行し、代入される値(ここでは0)を解決します。したがって、間違い終了ステータス。

$((...))算術展開構文を使用すると、終了ステータスの基になる値を確認できます。

$ echo "$((1 + 1)) $((2 == 2)) $((2 == -2)) $((var = -2)) $((var += 2))"
2 1 0 -2 0

または、変数に代入します。

$ var=-2; ((result = (var += 2)))
$ echo "$? $result $var"
1 0 0

$?if前のコマンドの終了ステータスが含まれます。/// に関しては、0 は true を意味し、thenそれ以外は false を意味します。elsefi

ここでの混乱は、算術式の場合は逆になるという事実から生じます。つまり、 は0false を意味し、それ以外は true を意味します (たとえば、は2 == 2ですがは です)。12 < 10

違いを気にしないためには、$?とその可能な値を忘れてください。ブール値で考えてください。真実/間違い成功/失敗

 grep -q foo file

fooが に見つかった場合は true を返しますfile

 [ "$a" = "$b" ]

$aと同じものが含まれている場合は true を返します$b

 ((6 * 3 - 12))
 ((4 == 1))

算術式の結果がゼロ以外の数値の場合は true を返します。

それが真実/間違いgrepこれらの/[コマンドまたは((...))構文の終了ステータスの 0 または 1 で表現されます。

答え2

(c) 0 && 1は0の存在ステータスを作成し、それがifコンストラクトによって使用される。

間違いがあります。 0 && 1 の結果は です1。 これは C や Java ではないことに注意してください。 シェルでは、 から得られる結果は 0 && 1 ですtrue && false

$ true; echo $?
0
$ false; echo $?
1
$ true && false; echo $?
1

また、さまざまな bash テキストで終了ステータスと戻りステータスが互換的に使用されているのを目にします。

これらは互換性があります。覚えておいていただきたいのは、 は0成功を示し、 以外が失敗を示すということです。これは、 が偽で が真である0ほとんどのプログラミング言語とは逆です。01

答え3

すべてが期待通りに動作しています。

if var=-2 && (( var+=2 ))
then
    echo "True"
else
    echo "False"
fi

コードの説明:-

if var=-2 && (( var+=2 ))

var=-2 => true 値はゼロではないので、trueと評価されます

var+=2 => false 値はゼロなので偽と評価されます

これは

if true && false

論理計算によれば真 && 偽 => 偽

その場合、最終的なコードは次のようになります

if (false)
then
    echo "True"
else
    echo "False"
fi

関連情報