(まだ)別の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
質問1:スクリプトでは、combine
は、両方のsomethingElse
プロセスが続行する間、両方のsomething
プロセスが完了するのを待機しますか?
質問2:そうでない場合-そして、そうではないと思われる場合-上記のcombine
プロセスが機能している間、somethingElse
が両方のsomething
プロセスのみを待機するようにする方法バックグラウンドで離れていますか?
あなたの例では、combine
コマンドはサブシェルが終了するとすぐに実行されます(最後のバックグラウンドプロセスがエラーなしで開始された場合)。 wait
コマンドがないため、サブシェルはジョブの開始直後に終了します。
2つ以上の同時バックグラウンドプロセスの戻り値に基づいてコマンドを実行する場合、戻り値に一時ファイルを使用する以外に方法はありません。これは、wait
が返すことができるのは、待機しているプロセスのoneの戻り値のみであるためです。また、バックグラウンドプロセスは、戻り値を取得するためにサブシェルで実行する必要があるため、変数に格納できません。あなたがすることができます:
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
ファイルOutputA
とOutputB
を保存する必要がなく、Result
のみを気にする場合は特に、プロセス置換がより効率的でしょうか?ディスクへの書き込みでI/Oが遅い場合、ファイルOutputA
とOutputB
の保存がレート制限ステップになる可能性があるため、これは特に時間の節約になりますか?
_combine <(somethingElse InputA) <(somethingElse InputB) > Result
_
プロセス置換を使用すると、出力をファイルに保存して「結合」ステップで入力として読み取る代わりに、コマンドを<(..here..)
内に配置できます。
メモリが制限であり、outputA
およびoutputB
のサイズがメモリが保持できるサイズよりも大きい場合、目的全体を無効にしますか?
combine
は、両方のプロセスが完了するまで待機してから実行を開始しますか?
wait
コマンドを使用できます。
(echo starting & sleep 10 & wait) && echo done
「開始」の行がすぐに発生し、「完了」が10秒間待機することがわかります。