&&および||の混乱した使用 オペレーター


93

私は流し読みました/etc/rc.d/init.d/sendmail(私はこれはめったに使用されているけど、私は受験のために勉強しています)ファイル、および私は約少し混乱になった&&||演算子。次のようなステートメントでそれらを使用できる場所を読みました。

if [ test1 ] && [ test2 ]; then
     echo "both tests are true"
elif [ test1 ] || [ test2 ]; then
     echo "one test is true"
fi

ただし、このスクリプトは次のような単一行のステートメントを示します。

[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE"
[ -f /usr/sbin/sendmail ] || exit 0

これらは&&and ||演算子を使用してテストに基づいて応答を引き出しているように見えますが、これらの演算子のこの特定の使用に関する説明を掘り下げることはできませんでした。誰もがこれらがこの特定のコンテキストで何をするのか説明できますか?

回答:


141

の右側&&は、左側の終了ステータスがゼロ(つまりtrue)の場合にのみ評価されます。||反対です。左側の終了ステータスがゼロ以外(つまりfalse)の場合にのみ、右側を評価します。

[ ... ]戻り値を持つプログラムであると考えることができます。内部のテストがtrueと評価された場合、ゼロを返します。それ以外の場合はゼロ以外を返します。

例:

$ false && echo howdy!

$ true && echo howdy!
howdy!
$ true || echo howdy!

$ false || echo howdy!
howdy!

追加のメモ:

するとwhich [[実際にプログラムを指していることがわかります。ただし、実際にはスクリプトで実行されるものではありません。実行type [して、実際に実行されるものを確認します。プログラムを試してみたい場合は、次のようにフルパスを指定してください/bin/[ 1 = 1


6
「XまたはY」が表示されたら、Xをテストします。それが真の場合、「XまたはY」に対する答えは既にわかっているので(本当です)、Yをテストする必要はありません。 「XまたはY」に対する答えなので、Yをテストする必要があります。「XおよびY」が表示されたら、Xをテストします。それが偽の場合、「XおよびY」に対する答えは既にわかっています(偽) Yをテストする必要はありません。Xがtrueの場合、Yをテストして「X and Y」がtrueであるかどうかを確認する必要があります。
デビッドシュワルツ

2
「左側がゼロを返す場合」の代わりに、「左側のコマンドの終了ステータスがゼロの場合」と書きます。私は、出力と終了ステータスとして曖昧ビットの両方が「戻り値」とみなすことができる「リターン」を見つける
グレン・ジャックマン

「プログラムであると考える 」ことができるだけでなく[ ... ]、多くの場合そうです。通常、ファイル/bin/[またはにあります/usr/bin/[
LS

5
Cプログラマーにとっては、これは非常に紛らわしいでしょう。0はfalseを意味します...シェルスクリプティングでは0はtrueを意味します。
カルマリオス

あなたが言及することができる別のものはtestifまたはの代わりです[。そして、if [if testが点在しているようだ[test明白な韻または理由で。Fedora x86_64上のベンダーライブラリのconfig.siteのtestように、時々表示されます。

59

ここに私のチートシートがあります:

  • 「A; B」Aの成功に関係なく、Aを実行してからBを実行します。
  • 「A && B」Aが成功したらBを実行
  • 「A || B」Aが失敗した場合はBを実行します
  • 「A&」バックグラウンドでAを実行します。

JavaScriptの動作(変数を順番に定義する)で示されている興味深いラムダ計算の並列処理がここで行われています。"(別名真)左": (a => b => a)。"右(別名偽)": (a => b => b)。「A; B」「その後」(a => b => (() => b())(a()))。"A && B" "他のない場合は()" (a => b => a()(() => right)(b))。「A || B」「if(unless)なしのその他」(a => b => a()(b)(() => right))。"a && b || c" "ifThenElse" (a => b => c => (unless(when(a)(b))(c))())
ドミトリー

1
bashでは、左が類似の0 /空の文字列であり、右が類似であることに注意してください。
ドミトリー

28

上から@ Shawn-j-Goffの答えを展開するに&&は、論理ANDであり||、論理ORです。

Advanced Bash Scripting Guideのこの部分を参照してください。以下のように、ユーザーが参照するためのリンクの内容の一部。

&& AND

if [ $condition1 ] && [ $condition2 ]
#  Same as:  if [ $condition1 -a $condition2 ]
#  Returns true if both condition1 and condition2 hold true...

if [[ $condition1 && $condition2 ]]    # Also works.
#  Note that && operator not permitted inside brackets
#+ of [ ... ] construct.

|| または

if [ $condition1 ] || [ $condition2 ]
# Same as:  if [ $condition1 -o $condition2 ]
# Returns true if either condition1 or condition2 holds true...

if [[ $condition1 || $condition2 ]]    # Also works.
#  Note that || operator not permitted inside brackets
#+ of a [ ... ] construct.

11

私の経験から、&&と||を使用します ifステートメントを1行に減らします。

/root/Sample.txtというファイルを探している場合、従来の反復はシェルでは次のようになります。

if [ -f /root/Sample.txt ]
then
    echo "file found"
else
    echo "file not found"
fi

これらの6行は、1行に減らすことができます。

[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"

変数を設定したりファイルなどを作成するために数回の反復を実行する場合、人生はより簡単で、スクリプトは単一行のif関数を使用して滑らかに見えますが、唯一の欠点は、単一の反復から複数のコマンドを実装することが少し難しくなることです関数を使用できます。


これはカッコいい。objcコード(a == b)を思い出させますか?val = 1:val = 2;
GeneCode

「&」を使用してバックグラウンドでプロセスを実行する場合、このコマンドを使用するにはどうすればよいですか?構文エラーが表示されます./someScript.sh & && echo 'ok' || echo 'ko'
ケイティ

4

「ショートカット」の概念があります。

(expr1 && expr2)評価時- 評価が「true」のexpr2場合にのみ評価exp1されます。これは、expr1AND expr2がtrueであるため(expr1 && expr2)にはtrueである必要があるためです。expr1「false」expr2と評価された場合、(expr1 && expr2)すでに「flase」であるため、評価されません(ショートカット)。

以下を試してください-ファイルF1が存在し、ファイルが存在F2しないと仮定します:

( [ -s F1 ] && echo "File Exists" )  # will print "File Exists" - no short cut
( [ -s F2 ] && echo "File Exists" )  # will NOT print "File Exists" - short cut

||(または)の場合も同様ですが、ショートカットは逆になります。


5
ロジックは通常「短絡」と呼ばれます。「ショートカット」という言葉が使われるのを見たことがありません。これは、参照の検索に役立つように言及しています。
LS

-1

Shawn J. Goffの回答の例は正しいですが、説明は逆です。チェックしてください:

&&の右側は、左側の終了ステータスがNONZEROの場合にのみ評価されます。|| 逆です。左側の終了ステータスがゼロの場合にのみ、右側を評価します。


3
シェルの場合、ゼロの終了コードはtrueと評価されるため、式全体の結果の左側にあるゼロ以外の終了コードはfalse&&を返します
カウンター

1
それがあなたの答えではなかったので、誰かがあなたの編集を承認しませんでした。いくつかの答えが間違っていると思われる場合は、それをダウン投票し、コメントを残す必要があります。変更が必要だと思われる場合は、コメントを残してください。編集とは、回答の意味を変えない文法、書式設定、およびスペルミスを修正することです。
テクラフ

1
@countermodeごめんなさい、あなたは正しい、Linuxではzero = falseおよびnonzero = true(Cや他の多くの言語/環境/プラットフォームのように)と思った。誤解して申し訳ございません。
Try2Help
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.