組み込みのWaitの予期しない動作が発生しました。
~
❯ sleep 1 &
[1] 72009
~
❯
[1] + 72009 done sleep 1
~
❯ wait 72009
~
❯ echo $?
0
PID が存在しなくても、待機はまだゼロ終了状態で終了します。
質問
- この行動の理由は何ですか?
- 待機はどのように行われますか?後ろでは何をしていますか?
答え1
この場合、Bash はwait
プロセス 72009 が子プロセスの 1 つであることを「記憶」し、子プロセスの終了コードである 0 を記憶するため、0 を返します。 (文書には「アクティブ」プロセスが明示的に記載されているため、少し誤解を招く可能性があります。)
その後、wait
指定されたプロセス識別子がシェルのサブプロセス(おそらくタスク内)の1つに対応することを確認します。その場合は、そのプロセスがまだ実行中であることを確認してください。まだ実行中の場合は、完了するまで待ちます。完了したら、適切な終了コード(プロセスにのみ適用されるか、ジョブ全体に適用されます)を決定し、その終了コードを返します。信号処理、プロセス置換、端末制御などを適切に処理するには、追加の複雑さがたくさんありますが、ここでは関係ありません。
終了コードは(少なくとも)ワークシートに保存されます。異なる終了コード(false &
およびtrue &
)を使用して2つのコマンドを実行し、対応するプロセス識別子を待つと、これが実際にどのように見えるかを確認できます。タスクリストがクリアされない限り、wait
正しい終了コードが提供されます。wait
ジョブテーブルから完了したジョブを削除するために引数なしで実行すると、前のジョブの終了コードを取得できなくなることがわかります。
答え2
これがwait
シェルで組み込み関数を定義する方法です。
- 終了した子プロセスを待つと
wait
0が返されます。
一部のシェル(例:)ksh93
には、最後のいくつかのプロセスのキャッシュがあり、これらの子プロセスの終了コードを返すことがあります。