bashモードの意味は何ですか[...] & wait $!
?たとえば、
curl -LsS $AZP_AGENT_PACKAGE_LATEST_URL | tar -xz & wait $!
私はこれを次のように理解します。
&
バックグラウンドサブシェルで古いパイプラインを実行するようにbashに指示します。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 "$!"'
bash
sleep
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
失われることです(オプションが設定されていない場合の終了ステータスは$PIPESTATUS
1つのエントリのみを含む)。wait
B
pipefail
In zsh
、in A | B
、zsh
wait 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
Ouch
SIGTERM
出力に送信されるとbash
(sleep 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
。
スクリプト作成者がこれらの副作用を意図したかどうかは、別の問題です。スクリプトで他の多くのエラーが見つかり、スクリプトを書いた人はシェルスクリプトについてよく知らない可能性があります。