「&&」と「;」に違いはありますか 標準のBASH端末のシンボル?


56

彼らは両方とも、シンボルに続く別のコマンドで開始するようにBASHに信号を送るようですが、明確な違いはありますか?

回答:


75

この行では:

command1 && command2

command2は、command1が終了ステータス0を返した場合にのみ実行されますが、次の行では:

command1 ; command2

関係なく、command1とcommand2の両方が実行されます。セミコロンを使用すると、1行に多くのコマンドを入力できます。


1
面白い!もっと快適な方法だと思っていました。ありがとうございました!

42

あなたは自分で違いを試すことができます:

  1. ls /invalid/path && echo "hello!"
    / invalid / pathが存在しないため、lsはディレクトリリストを表示できません。「ls:/ invalid / path:No such file or directory」というエラーメッセージで失敗します。後半コマンドのは、(「こんにちは!」エコー)されても、実行されたことがない前半が失敗したため。

  2. ls /invalid/path ; echo "hello!"
    前と同じエラーメッセージが表示されますが、今回は2番目の部分が実行されます!
    ls:/ invalid / path:そのようなファイルやディレクトリはありません

なぜこれが便利ですか?
archive.tar.gzというファイルを抽出するとします。
コマンドを使用できますtar zxvf archive.tar.gz && rm archive.tar.gz
何らかの理由でアーカイブの抽出が失敗した場合、2番目の部分は実行されません!再試行できます。

使用する場合; 同じ状況では、アーカイブは削除され、再試行できません。


8

&&isですAND。2番目のコマンドは、最初のコマンドがtrue(エラーなし)を返した場合にのみ実行されることを意味します。


1
&&は「then」(「and」ではない)です...私の答えを参照してください
-Peter.O

2
@fred 短絡評価のある「and」だと思います-最初の部分がtrueでない場合、合計結果がfalseでなければならないことを知っているので、2番目の部分をスキップします。しかし、それを「それから」と考えることは、この文脈ではめったに大きな違いをもたらさないことに同意します。
jgファウスタス

2
@fred概念的にはそのように理解する方が簡単かもしれませんが、あなたの声明には同意しません。アイデアは、最初のパラメーターが等しい場合、どのような AND実行でも2番目のパラメーターは無関係になるfalseため、最初のパラメーターが何であるかがわかるまで2番目のパラメーターの評価を延期するように基になるコードが最適化されるというものです。
ワードミュイラート

2
@fredその例がどのようなポイントを作ろうとしているのか分かりません。&&は単なる二項演算子、関数です。唯一の「特別な」ことは、それが中置記法(とにかくこれらの種類の演算子のほとんどに標準である)と第2オペランドの遅延実行であることです。実際、遅延した実行により、このコンテキストで概念的にifステートメント見なすことができるものとして使用できるようになりますが、本来意図された使用法が実際のステートメントの条件内にあるという事実から離れることはありませんif。ここでの使用は、実際には「ハック」のようなものです。
ワードミュイラト

3
@fredもちろん、三項演算子ではなく、2つの操作の連続ですa && b || c = (a && b) || c。評価の単純な順序。そこには本当に謎はありません。あなたが典型的な関数のようにそれらを書くなら、それは単にのように見えるでしょうor(and(a, b), c)。and は演算子であり、2つのオペランドを取り、別のオペランドを返すifため&&、このロジックは条件内でもコマンドラインに直接入力する場合でも同じです。||
ワードミュイラト

8

更新:可能性のあるいくつかのトラップをスクリプトに追加しました:

誰も「||」に言及していないので、私は

Update2:ここで重要な言い回し
&&は、「true」に応答する「if」ステートメントの「then」のようなものです。

|| されない「IF」なステートメントの「他の」好き..
|| 「false」に応答する「if」ステートメントの「then」のようなものです

より具体的には、&&は$?をテストします。直前に実行され直前の ステートメントの値を返し、&& ...の直後のステートメントまたはサブシェルに制御を渡します。本当です。

|| 類似しており、多くの場合、&&文の後に見ているが、それはテストのためにの戻り値($?)前の 最後に実行された声明... NB!、Nota Bene!よく注意してください!.... predecingステートメントが&&ステートメントであり、trueであると予想されるときにfalseを再実行する場合、|| falseに応答するため、同じ行に両方を混在させることは危険です

私がしようとしている主なポイントは、私が犯した間違いに関連しています。すなわち:
## [[条件]] && A || Bは
されていない C / C ++スタイルの三元のように動作しません。すなわち:
//(条件)?A:B
「A」からの「予期しない」結果の例については、以下のスクリプトを参照してください

基本テストと&&および|| 文はすべて同じ行になければなりません...


このスクリプトを実行して、&&および||の使用時に問題が発生する可能性のある場所を確認します。最後に実行文では、あなたが期待する1ではないかもしれません。..

[[condition]] && echo Hello || echo Goodbye ....は、通常は安全です。
整形式のエコーがtrueを返すためです。
しかし、終了しないファイルにアクセスするのはどうですか?

#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \$0  0   rc=$? ..&&.. condition is true" || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && echo  " ((1!=1)) rc=$? ..&&.. condition is true" || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && echo "  \$0  1   rc=$? ..&&.. condition is true" || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo  ======
 ((1==1)) || echo  " ((1==1)) rc=$? ..||.. condition is true" && echo  " ((1==1)) rc=$? ..&&.. condition is false"
  $0  0   || echo "  \$0  0   rc=$? ..||.. condition is true" && echo "  \$0  0   rc=$? ..&&.. condition is false"
 ((1!=1)) || echo  " ((1!=1)) rc=$? ..||.. condition is true" && echo  " ((1!=1)) rc=$? ..&&.. condition is false"
  $0  1   || echo "  \$0  1   rc=$? ..||.. condition is true" && echo "  \$0  1   rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \$0  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \$0  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \$0  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \$0  1   rc=$? ..||.. condition is false"

exit 



0

後のコマンド(スクリプトの場合は関数)&&は、最初のコマンド(スクリプトの場合は関数)のRETVALに応じて実行されます。成功した場合、最初のコマンドは値0を強制的に返します。戻り値を確認して、さらにコマンドを実行できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.