`[...]&wait$!`の意味

`[...]&wait$!`の意味

bashモードの意味は何ですか[...] & wait $!?たとえば、

curl -LsS $AZP_AGENT_PACKAGE_LATEST_URL | tar -xz & wait $!

私はこれを次のように理解します。

  1. &バックグラウンドサブシェルで古いパイプラインを実行するようにbashに指示します。
  2. wait $!次に、返す前にパイプラインが完了するのを待ちます。

しかし、もしそうなら、パイプライン自体を実行するのとどう違いますか?ポイントは何ですか?

この例(およびその他の例)を含むスクリプトは、以下にあります。

https://docs.microsoft.com/en-us/azure/devops/pipelines/agents/docker?view=azure-devops

答え1

非対話型シェルでコマンドを非同期的に実行すると、2つの異なるA副作用がありますA & wait "$!"

  • .SIGINTとSIGQUITは無視されますA。実行中に+を押すとCtrl終了することがわかりますが、終了しません。Cbash -c 'sleep 1000 & wait "$!"'bashsleep

  • A標準入力は次にリダイレクトされます/dev/null

    $ bash -c 'readlink /dev/fd/0'
    /dev/pts/4
    $ bash -c 'readlink /dev/fd/0 & wait "$!"'
    /dev/null
    

もう1つの違いは、A | B & wait "$!"$!実行されたプロセスのpidを含むB)での終了ステータスがA失われることです(オプションが設定されていない場合の終了ステータスは$PIPESTATUS1つのエントリのみを含む)。waitBpipefail

In zsh、in A | Bzshwait A、in B、しかしinA | B & wait $!でのみ待機しますB(使用してもinの終了状態はA失われますpipefail)。

もう1つの違いは、シグナルがシェルに渡されるとwaitすぐに処理され返されます(待機中のプロセスがまだ完了していない場合でも同様です)。

比較する:

$ bash -c 'trap "echo Ouch" TERM; sleep 10 & wait "$!"; echo "$?"' & sleep 1; kill "$!"
[1] 13749
Ouch
143

OuchSIGTERM出力に送信されるとbashsleep 10終了後も続行)、次のようになりますbash

$ bash -c 'trap "echo Ouch" TERM; sleep 10; echo "$?"' & sleep 1; kill "$!"
[1] 13822
$ Ouch                                                                                                                                        6:11
0

[1]  + done       bash -c 'trap "echo Ouch" TERM; sleep 10; echo "$?"'

Ouch返却後に出力する位置ですsleep 10

スクリプト作成者がこれらの副作用を意図したかどうかは、別の問題です。スクリプトで他の多くのエラーが見つかり、スクリプトを書いた人はシェルスクリプトについてよく知らない可能性があります。

関連情報