論理演算子とセミコロンの優先順位

論理演算子とセミコロンの優先順位

bashにこのような行を書くとどうなりますか?

commandA && commandB ; commandC

commandA失敗するとcommandC処刑されますか?

答え1

はい、直接簡単に確認できます。

$ non-existent-command && echo hi ; echo after semicolon
bash: non-existent-command: command not found
after semicolon

内容man bashは次のとおりです。

コマンドは;;で区切られ、順番に実行されます。シェルは、各コマンドが順番に終了するのを待ちます。

答え2

Bashのマニュアルページによると

[L]ist演算子&&と||は同じ優先順位を持ち、その後は同じ優先順位を持ちます。

実際、これは結果の返却に興味を持っている人が誰であるかによって異なります。結果がすぐに必要な場合は、優先順位が高くなります。

答え3

commandCcommandA失敗したか成功したかにかかわらずcommandB実行されます。

セミコロンは、コマンドを順次実行するための区切り記号だけです。commandCこれが失敗する可能性のある唯一のシナリオはcommandA次のとおりです。commandBexitコマンド(または/ / /(またはこれらのコマンドを呼び出す関数)などのワークフローに強制的に影響を与えるコマンドreturnbreakcontinueexec

シナリオ1:commandAはいexit

[root@host ~]# exit && echo "HI"; echo "test"
logout
[user@host ~]$

シナリオ2:commandBはいexit

[root@host~]# echo "HI" && exit; echo "test"
HI
logout
[user@host ~]$

簡単に言うと: そのキャラクターが優先権を持つという意味ではないですか?彼らの意味は異なります。 1 つは論理演算子、もう 1 つはリスト終端子です。

関連情報:

  • シェルの制御およびリダイレクト演算子は何ですか? この答えはbash演算子を非常によく説明します。答えの短い引用は次のとおりです。

    • ;: 最初のコマンドの結果に関係なく、他のコマンドが完了した後に 1 つのコマンドを実行します。

      command1 ; command2
      

      まずcommand1、前景で実行し、完了すると command2実行されます。

      文字列リテラルにないか、特定のキーワードの後に​​改行がありません。 いいえセミコロン演算子と同じです。単純なコマンドの区切りリスト;はまだあります。リスト- シェルのパーサーと同様に、実行する前に読み続ける必要があります。; 改行文字は、コマンドのリスト全体またはリストのリストを区別できます。違いは微妙ですが複雑です。改行は、シェルが改行後のデータを読み取る前のコマンドがないと仮定し、シェルが読み取った単純なコマンドの評価を開始できる点を示しますが、セミコロンはそうではありません;

  • シェルスクリプト行の末尾にセミコロンが重複していますか?  答えを引用するには:

    改行文字もコマンド区切り文字であるため、行末の単一のセミコロンは重複します。  case特に、各パターンブロックの最後のコマンドの最後に二重セミコロンを使用する必要がありますhelp case

  • セミコロンとデュアルアンパサンド&&の違いは何ですか

答え4

他の記事で述べたように、短い答えは「はい、commandCあなたは何が起こっても処刑されます」です。

〜のようにエンワイルドや探検、より長い答えは次のとおりです。 「はい、commandC何が起こってもシェルは実行可能な状態である限り実行されます。commandCつまり、シェルはそれ以上実行を続行しません。

commandA && commandB ; command

実行せずにコマンドラインを実行しますcommandC。 」

簡単に言えば、commandA(またはcommandB)がkill -KILL $$ シェルを終了または破損させたり、コマンドフローを妨げる他のものであればcommandC実行されません。 (明らかにここでは極端なケースについて話しています。)set -e (またはそれに対応するset -o errexit)が解放されると、動作は少し異なります。

  • commandA失敗するとcommandC実行されます(ただしcommandB実行されません)。
  • commandA成功するとcommandB実行されます。
    • commandB成功するとcommandC実行されます。
    • これが失敗すると、commandBシェルは次commandCのように終了します。いいえ処刑された。

このerrexitオプションは、コマンド(「パイプライン」)が失敗した場合にシェルが終了することを指定します。ただし、いくつかの例外はあります。

while失敗したコマンドが、またはキーワードの直後のコマンドのリストの一部であるか、予約語の後のuntilテストの一部、またはa内で実行されたコマンドの一部である場合、シェルは終了しません。ifelif&&または||最後のコマンドを除くコマンド&&||最後のコマンドを除くパイプラインのすべてのコマンド、またはコマンドの戻り値が反転した場合のリストを表示します!

- から大きな打撃(1)

したがってcommandA、失敗すると、次のようcommandBに実行されない結果のみが発生します。commandA&&。ただし、実行に失敗すると()が(final)に従うcommandBため、シェルは終了します。commandB&&

関連情報