この質問では、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コマンドの一部です。
if1 つまたは複数のコマンド (またはパイプライン) を実行し、最後に実行されたコマンドからのリターン コードが成功した場合は、到達するまでコマンドを実行しますthen。fi戻りコードが成功しなかった場合、そのthen部分はスキップされ、実行は の後に続行されfiます。
if いずれにせよ、その動作は変更できません。
if上記の例では、実行するように指示したコマンドはtrue. true構文やキーワードではなく、単なる別のコマンドです。単独で実行してみてください:
true
何も出力しませんが、戻りコードを0(別名「true」) に設定します。if上記のステートメントを次のように書き直すと、コマンドであることがより明確にわかります。
if /bin/true ; then echo 1 ; fi
これは完全に同等です。
テストから常に true を返すことはあまり役に立ちません。コマンドifと組み合わせて使用するのが一般的です。にシンボリックリンクされているか、そうでない場合もあります。システムにはおそらくプログラムがありますが、使用している場合は組み込みコマンドになります。よりも複雑なコマンドであり、すべてを読むことができます。testtest[/bin/[bash [testif
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。ここでは、test4 つの引数を渡しています。2 番目の引数は、最初の引数が 3 番目の引数より小さいかどうかを確認するために、1 番目の引数と 3 番目の引数をテストする必要があることを-lt示すスイッチです。test4 番目の引数は、コマンドの終わりを示すだけです。最後の引数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 falsetruetrue-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 としてテストされ、成功を返します。これは で逆になり、ステートメントを実行しない に!渡されます。ifthen
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。