Or&And演算子を使用するのは混乱しています。

Or&And演算子を使用するのは混乱しています。
echo 1 && false && echo 2 || echo 3
1
3

echo 2 || echo 3
2

上記のコードで最初のケースでは、なぜ2が印刷されないのですか? 2番目のケースでは、なぜ2が印刷されますか?

答え1

より一般的な質問シェルの制御およびリダイレクト演算子は何ですか?その答えはおそらくあなたの質問に対する答えになるでしょう。しかし、参考にするために、いくつかの経験則を提示します。

  • 長いリストおよび/またはリストがある場合は、各リストを||「このリストの最後に実行された部分」として扱うことができます。失敗、次のセクションを実行してください。」(ここで「失敗」はゼロ以外の終了ステータスを返すことを意味します)

  • 同じタイプの推論を使用すると、「&&このリストで最も最近実行された部分成功、次のセクションを実行してください。

上記の内容は一般的に知られているものである。段落評価

コードを例として、各コードをecho実行する機会があるとします(echo交換失敗する標準出力ストリームが閉じられた場合):

echo 1 && false && echo 2 || echo 3

最初はecho 1成功してfalse実行されます。 false(設計上)失敗するのでecho 2 確かにランニング。echo 3、一方、false最後に実行された list() 部分が失敗したために実行されます。

見ている

echo 2 || echo 3

これはecho 2最初に実行されますが、echo 3リスト内の最後に実行された部分が失敗しなかったためではありません。

答え2

&&||この答えの簡単な説明があります。https://unix.stackexchange.com/a/31881/4506mしかし、具体的な例の詳細な説明は次のとおりです。

まず、Unixコマンドを知ることが重要です成功または失敗する彼らがどのような成果物を生産するか、または生産しない可能性があるかに関係なく。より正確に言えば、コマンドは終了状態が 0 であれば成功し、終了状態が 0 でなければ失敗します。しかし、終了状態の観点から考えるのは混乱しています。

これを考えると考えることができます。

  • cmd1 && cmd2 && ... && cmdNコマンドは失敗するまで左から右に評価されます。
  • cmd1 || cmd2 || ... && cmdNコマンドは成功するまで左から右に評価されます。

さあ、始めましょう。あなたの最初の例

echo 1 && false && echo 2 || echo 3

&&括弧がないと、組み合わせと操作がさらに混乱し、意図した||グループ化が不明瞭になります。&&とは||優先順位が同じで左にグループ化されていることがわかりましたが、このように混在したシーケンスはしばしば混乱します。この表現の正確な意味は

( ( ( echo 1 && false ) && echo 2 ) || echo 3 )

さて、どうしたの?

  • シェルは評価を開始します( ... || echo 3 )が、これを行うにはまず左のコマンドを評価する必要があります。

  • シェルは評価を開始します( ... && echo 2 )が、これを行うにはまず左のコマンドを評価する必要があります。

  • シェルは評価を開始します( echo 1 && false )が、これを行うにはまず左のコマンドを評価する必要があります。

  • シェルはecho 1常に成功を評価します。つまり、ステータスコード0で終了します。echo 1演算子は、何かが印刷されるという事実には気にしませんが、&&出力の最初の行であると解釈します1\n

  • 最初のオペランドの左側のオペランドが( echo 1 && false )成功するため、シェルは右側のオペランドを評価し続けますfalse。常に失敗するコマンドなので、&&式全体が失敗します。

  • の左オペランド( ... && echo 2 )が失敗したため、シェル確かに実行され、echo 2式自体が失敗します。

  • 左のオペランドが( ... || echo 3 )失敗するので、シェルはする実装するecho 3。このコマンドは2番目の出力ラインを生成しますが、より重要なことは、演算子が||常に成功しているため、演算子のシーケンス全体がecho成功することです。&&||

  • コマンドを実行した後に入力すると、echo $?値は0として表示され、前のコマンドが成功したことを示します。

2番目の例これは上記と同じプロセスで評価できますが、さらに詳しく見てみましょう。

echo 2 || echo 3

これは最初の例よりはるかに簡単です。シェルは次の手順を実行します。

  • シェルは計算を開始しますecho 2 || echo 3が、これを行うにはまず左側を計算する必要があります。

  • シェル評価echo 2。これにより、1行の出力が正常に印刷されます。

  • シェルは引き続き評価しますecho 2 || echo 3が、今では左手が成功するため、ステータスルールは||右手をまったく評価しません(したがって他の出力行を取得できません)。左が成功するので、完全な||式が成功します。

かなり詳しく説明していますが、参考になれば幸いです。

答え3

シェルは厳密な左から右の順序でコマンドを実行します(ORおよびANDリストの場合)。

このコマンドでは:

echo 1 && false && echo 2 || echo 3

最初のコマンドはですecho 1。 echo の終了状態は常に 0 であるため実行され、終了状態は0(最初はすでに 0 であったにもかかわらず) になります0

最初のコマンドが見つかった場合、終了ステータス&&は0(上から)で実行が成功した後、&&次のコマンドが受け入れられて実行されることを意味します。

実行すると、false終了状態は1(失敗)になります。

nextが見つかると、&&現在の終了ステータスは1、&&拒否され、次のコマンド(echo 2)は実行されません。

ただし、その行にはまだ多くのコードがあるため、シェルは次の項目に移動します。この時点の現在の終了状態||で、次のコマンド()が受け入れられ、実行されます。1||echo 3

このコマンドはecho 2 || echo 3分析が非常に簡単です。最初のコマンドは(常に)終了コードを取得するために実行されます。終了コードは、0次のコード||が拒否されてecho 3実行されないことです。これ以上処理するものはありません。行末です。

関連情報