Bash、特定のバックグラウンドプロセスを実行し、他のプロセスを待つ方法は?

Bash、特定のバックグラウンドプロセスを実行し、他のプロセスを待つ方法は?

wait別の制御 &フローの問題があります&&

次のスクリプトがあり、同時にできるだけ多くのことをしたいとしましょう。

# may take some hours
something InputA > IrrelevantA &
something InputB > IrrelevantB &

# may take an hour
(
   somethingElse InputA > OutputA &
   somethingElse InputB > OutputB &
)&& combine OutputA OutputB > Result

...morestuff

Q1:スクリプトでは、combine両方のプロセスsomethingElseが継続している間に両方のプロセスが完了するのを待ちますかsomething

質問2:そうでない場合(私の考えではそうではありません)、上記のプロセスがバックグラウンドで実行され続けている間、どのようにこれらの2つのcombineプロセスを待つことができますか?somethingElsesomething

ベストアンサー1

あなたの例では、combineコマンドはサブシェルが終了した直後に実行されます(最後のバックグラウンドプロセスがエラーなしで開始されたと仮定)。コマンドがないため、waitジョブが開始されるとすぐにサブシェルが終了します。

複数の同時バックグラウンドプロセスの戻り値に基づいてコマンドを実行する場合は、一時ファイルを戻り値として使用する以外には他の方法はありません。wait戻り値のみを返すことができるからです。一つ待機中のプロセスの数。さらに、バックグラウンドプロセスは戻り値を取得するためにサブシェルで実行する必要があるため、変数に保存することはできません。次のことができます。

something InputA >IrrelevantA &
something InputB >IrrelevantB &

tmp1=$(mktemp)
tmp2=$(mktemp)

( somethingElse InputA >OutputA; echo $? >"$tmp1" ) &
proc1=$!

( somethingElse InputB >OutputB; echo $? >"$tmp2" ) &
proc2=$!

wait "$proc1" "$proc2"

read ret1 <"$tmp1"
read ret2 <"$tmp2"
[ "$ret1" = 0 && "ret2" = 0 ] && combine OutputA OutputB >Result

rm "$tmp1" "$tmp2"

戻り値にあまり興味がない場合は、ジョブを正常に開始して次のことを使用できますwait

something InputA >IrrelevantA &
something InputB >IrrelevantB &

somethingElse InputA >OutputA &
proc1=$!

somethingElse InputB >OutputB &
proc2=$!

wait "$proc1" "$proc2"
combine OutputA OutputB >Result

おすすめ記事