web-dev-qa-db-ja.com

&&と||の使い方の混乱演算子

私は/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

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

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

これらは、テストに基づいて応答を引き出すために&&および||演算子を使用しているようですが、これらの演算子のこの特定の使用に関するドキュメントを詳しく調べることはできませんでした。誰もがこれらがこの特定の文脈で何をするか説明できますか?

105
josh-cain

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

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

例:

$ false && echo howdy!

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

$ false || echo howdy!
howdy!

補足:

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

159
Shawn J. Goff

これが私のチートシートです:

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

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

Advanced Bash Scripting Guideの this の部分を参照してください。以下のようにユーザー参照用のリンクからのコンテンツの一部。

&& 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.

|| OR

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.
30
Tim Kennedy

私の経験から、&&と||を使用します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関数の1行を使用して滑らかに見えますが、唯一の欠点は、単一の反復から複数のコマンドを実装するのが少し難しくなることです。関数を利用できます。

13
syme89

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

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

以下を試してください-ファイル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

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

4
Larry