2

この質問では、bash で適切なブール変数を使用する方法が示されています。そのような変数で論理演算を実行する方法はありますか? たとえば、これを取得する方法:

var1=true
var2=false
# ...do something interesting...
if ! $var1 -a $var2; then     <--- doesn't work correctly
   echo "do sth"
fi
4

3 に答える 3

7

これは機能します:

if ! $var1 && $var2; then
   echo "do sth"
fi

-a および -o 演算子と &&, ||, ! が機能しない理由を誰かが説明できるかもしれません。行う?

于 2012-06-18T08:06:57.760 に答える
5

よし、男子も女子も、レッスンタイム。

この行を実行するとどうなりますか?

if true ; then echo 1 ; fi

ここで起こっていることは、ifコマンドが実行されているということです。その後、起こることはすべてifコマンドの一部です。

if1 つまたは複数のコマンド (またはパイプライン) を実行し、最後に実行されたコマンドからのリターン コードが成功した場合は、到達するまでコマンドを実行しますthenfi戻りコードが成功しなかった場合、その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

しかし、繰り返しになりますが、これは常に真であるため、あまり役に立ちません。12が変数だったらもっと便利だろう

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新しい[[コマンドを使用する必要があります。これは、より強力であり、互換性の理由から に保持しなければならない多くの落とし穴をなくすため[です。

元のポスターは彼が達成しようとしていることの現実的な例を提供していないため、最善の解決策について具体的なアドバイスを与えることは困難です. 願わくば、これが十分に役に立ち、彼が今やるべき正しいことを理解できるようになったことを願っています。

于 2012-06-18T11:58:44.313 に答える
1

ここでは、2 つの異なる構文が混在しています。

これはうまくいきます:

if ! [ 1 -a 2 ]; then
   echo "do sth"
fi

式が括弧で囲まれていることに注意してください。

これらのキー (など) を使用するには、testコマンド (新しい構文)が必要です。[-a-o

しかし、testコマンド自体を実行します。コマンドの終了コードを確認したい場合は、使用しないでくださいtest

于 2012-06-18T08:14:34.090 に答える