「$!」は「&」を使用して正しいIDを確実に返しますか?

「$!」は「&」を使用して正しいIDを確実に返しますか?

私のテストでは、これまでは常に正しい結果を得ました。

[fabian@manjaro ~]$ sleep 10 & echo $!
[1] 302657
302657

ただし、sleeptheとechohereが同時に実行されるため、正確にecho設定された値よりも前に実行されることが予想されます。$!このようなことが起こりますか?今までなぜ効果がなかったのですか?

私の究極の目標は、両方のタスクを並列に実行し、続行する前に両方のタスクを待つことです。現在の計画は同様のものを使用することですfoo & bar; wait $!; baz。これは常に機能しますか、または時々ランダムな前のバックグラウンドプロセスを待つことができますか(空であればまったく待たないかもしれません$!)?

答え1

だから

sleep 10 & echo $!

2つのコマンド

sleep 10 & 
echo $!

彼らが同じページにあることはそれを変えません。

したがって、シェルはfork()新しいプロセスを作成し、新しいプロセスのプロセスIDを$!。その後、新しいプロセスが実行され、sleep他のプロセスが実行されますecho

$!したがって、プロセスが失敗しても新しいプロセスのPIDが常に維持されるようにすることができますfork()

答え2

この目標を達成するには:

私の究極の目標は、両方のタスクを並列に実行し、続行する前に両方のタスクを待つことです。

これら2つのコマンドをbackground()に送信するスクリプトに含めると、すぐに起動して並列に実行できます。そのpidをキャプチャして明示的に待つ必要はありません&wait

task1 &
task2 &
wait
echo both tasks finished

posix マニュアルからwait:

スタンバイユーティリティがオペランドなしで呼び出されると、呼び出しシェルに知られているすべてのプロセスIDが終了し、ゼロ終了状態で終了するまで待ちます。

関連情報