Bash 4.4の変更ログによると:
https://lists.gnu.org/archive/html/info-gnu/2016-09/msg00008.html
bash-4.3とbash-4.4の間に互換性のない変更があります。 Bashは現在、すべてのジョブではなく非同期ジョブの終了状態のみを維持するようになりました。これは、以前に完了した同期コマンドの状態を検索するために「待機」を使用できないことを意味します。
https://fossies.org/diffs/bash/4.3.46_vs_4.4/CHANGES-diff.html
Bash は、多くの子プロセスを生成し、インポートスクリプト中にテーブルが大きくなりすぎないようにするために、状態を記憶する背景 pid テーブルにのみ非同期コマンドを追加します。つまり、「待機」は同期操作では動作しなくなりますが、そのような場合は終了ステータスを取得するために$?を使用できます。
私はすでに4.3と4.4の間の他の主要な変更でブロックされていますが、この特定の変更をテストするためにサンプルを作成する方法がわかりません。
Bashの同期操作と非同期操作の違いは何ですか?クエリ待機中のpidテーブルはどこに保存されますか?
ベストアンサー1
例:
4.3
bash-4.3$ (echo "$BASHPID"; exit 123)
5358
bash-4.3$ wait 5358; echo "$?"
123
4.4
bash-4.4$ (echo "$BASHPID"; exit 123)
12171
bash-4.4$ wait 12171
bash: wait: pid 12171 is not a child of this shell
wait
フォアグラウンドで(同期的に)実行されているサブシェルの終了ステータスを取得するために使用できなくなりました。展望対話型シェルの操作を参照しますが、非対話型シェルで実行されるコマンドにも同様に適用されます。
後で、次を介してフォアグラウンドにインポートするバックグラウンドタスクにも機能しますfg
。
bash-4.4$ (sleep 10; exit 123) &
[1] 12857
bash-4.4$ fg
( sleep 10; exit 123 )
bash-4.4$ wait 12857
bash: wait: pid 12857 is not a child of this shell
withbash-4.3
と before は、bash
過去の背景と前景コマンドのすべての終了状態を記憶します。通常、スクリプトのpidや次のことがわからないため、前景コマンドには役に立ちません。
cmd1 &
...
cmd2
wait "$!"
cmd1
PIDが再利用された可能性が高いですcmd2
。この場合、終了ステータスが代わりにwait "$!"
表示されます。非同期コマンドのpidのみを記録すると、コマンドの誤ったシャットダウン状態が発生するリスクがわずかに減少します(@ Christopherが述べたパフォーマンスの問題に加えて)。cmd2
cmd1
wait