この質問では、bash で適切なブール変数を使用する方法が示されています。そのような変数で論理演算を実行する方法はありますか? たとえば、これを取得する方法:
var1=true
var2=false
# ...do something interesting...
if ! $var1 -a $var2; then <--- doesn't work correctly
echo "do sth"
fi
これは機能します:
if ! $var1 && $var2; then
echo "do sth"
fi
-a および -o 演算子と &&, ||, ! が機能しない理由を誰かが説明できるかもしれません。行う?
よし、男子も女子も、レッスンタイム。
この行を実行するとどうなりますか?
if true ; then echo 1 ; fi
ここで起こっていることは、if
コマンドが実行されているということです。その後、起こることはすべてif
コマンドの一部です。
if
1 つまたは複数のコマンド (またはパイプライン) を実行し、最後に実行されたコマンドからのリターン コードが成功した場合は、到達するまでコマンドを実行しますthen
。fi
戻りコードが成功しなかった場合、そのthen
部分はスキップされ、実行は の後に続行されfi
ます。
if
いずれにせよ、その動作は変更できません。
if
上記の例では、実行するように指示したコマンドはtrue
. true
構文やキーワードではなく、単なる別のコマンドです。単独で実行してみてください:
true
何も出力しませんが、戻りコードを0
(別名「true」) に設定します。if
上記のステートメントを次のように書き直すと、コマンドであることがより明確にわかります。
if /bin/true ; then echo 1 ; fi
これは完全に同等です。
テストから常に true を返すことはあまり役に立ちません。コマンドif
と組み合わせて使用するのが一般的です。にシンボリックリンクされているか、そうでない場合もあります。システムにはおそらくプログラムがありますが、使用している場合は組み込みコマンドになります。よりも複雑なコマンドであり、すべてを読むことができます。test
test
[
/bin/[
bash
[
test
if
help [
man [
しかしここでは、 が指定したオプションに従っていくつかのテストを実行し、成功したリターン コード ( ) または失敗test
したリターン コードを返すとしましょう。0
これにより、私たちは言うことができます
if [ 1 -lt 2 ] ; then echo one is less than two ; fi
しかし、繰り返しになりますが、これは常に真であるため、あまり役に立ちません。1
と2
が変数だったらもっと便利だろう
read -p' Enter first number: ' first
read -p' Enter second number: ' second
echo first: $first
echo second: $second
if [ $first -lt $second ] ; then
echo $first is less than $second
fi
これで、それが機能していることがわかりますtest
。ここでは、test
4 つの引数を渡しています。2 番目の引数は、最初の引数が 3 番目の引数より小さいかどうかを確認するために、1 番目の引数と 3 番目の引数をテストする必要があることを-lt
示すスイッチです。test
4 番目の引数は、コマンドの終わりを示すだけです。最後の引数test
として呼び出すときは、常に でなければなりません。[
]
上記のif
ステートメントが実行される前に、変数が評価されます。に 20 をfirst
、 に 25 を入力しsecond
たとします。評価後、スクリプトは次のようになります。
read -p' Enter first number: ' first
read -p' Enter second number: ' second
echo first: 20
echo second: 25
if [ 20 -lt 25 ] ; then
echo 20 is less than 25
fi
test
そして、が実行されると testingになることがわかりますis 20 less than 25?
。これは true であるため、ステートメントif
が実行されます。then
目の前の質問に戻します。ここで何が起こっているのでしょうか?
var1=true
var2=false
if ! $var1 -a $var2 ; then
echo $var1 and $var2 are both true
fi
if
コマンドが評価されると、次のようになります
if ! true -a false ; then
これはif
実行を指示し、引数をコマンドにtrue
渡します。現在、スイッチや引数を取りませんが、必要なく指定してもエラーは発生しません。これは、それが実行され、成功を返し、パーツが無視されることを意味します。は成功を失敗に戻し、パーツは実行されません。-a false
true
true
-a false
!
then
上記を呼び出しtest
ているバージョンに置き換えた場合でも、期待どおりに機能しません。
var1=true
var2=false
if ! [ $var1 -a $var2 ] ; then
echo $var1 and $var2 are both true
fi
if
行は次のように評価されるため、
if ! [ true -a false ; ] then
test
ブール値のキーワードとしてではtrue
なく、コマンドとしてではなく、文字列として表示されます。空でない文字列は「true」として扱われるため、たとえあなたが言ったとしても、test
常に成功を返しますif
if ! [ false -a yourmom ] ; then
両方とも空でない文字列であるため、両方-a
とも true としてテストされ、成功を返します。これは で逆になり、ステートメントを実行しない に!
渡されます。if
then
test
バージョンをこのバージョンに置き換えると
if ! $var1 && $var2 ; then
次に、に評価されます
if ! true && false ; then
そして、次のように処理されます。成功を返すif
実行。これは;true
によって逆になります。!
最初のコマンドの戻りコードが失敗だったため、&&
ステートメントは短絡し、false
実行されません。実行された最後のコマンドが失敗を返したため、句if
を実行しないに失敗が返されます。then
これがすべて明確であることを願っています。
次のような構成を使用できることは、おそらく指摘する価値があります。
! false && true && echo 1
これは使用しませんif
が、リターンコードをチェックします。&&
それ||
が目的であるためです。
test
間違えずに使うには、一種の黒魔術があります。一般に、 を使用する場合は、代わりにbash
新しい[[
コマンドを使用する必要があります。これは、より強力であり、互換性の理由から に保持しなければならない多くの落とし穴をなくすため[
です。
元のポスターは彼が達成しようとしていることの現実的な例を提供していないため、最善の解決策について具体的なアドバイスを与えることは困難です. 願わくば、これが十分に役に立ち、彼が今やるべき正しいことを理解できるようになったことを願っています。
ここでは、2 つの異なる構文が混在しています。
これはうまくいきます:
if ! [ 1 -a 2 ]; then
echo "do sth"
fi
式が括弧で囲まれていることに注意してください。
これらのキー (など) を使用するには、test
コマンド (新しい構文)が必要です。[
-a
-o
しかし、test
コマンド自体を実行します。コマンドの終了コードを確認したい場合は、使用しないでくださいtest
。