
一連の長時間実行プロセスを起動するシェル スクリプトを作成しようとしています。これらを a、b、c、d、e と呼びます。プロセス b、c、d は並列に実行され、プロセス e は前のプロセスがすべて終了した後に実行する必要があります。成功。
私の(疑似)コードは次のとおりです:
{
echo "starting a"
a
}&&
{
(echo "starting b"; b; exit $?)&
(echo "starting c"; c; exit $?)&
(echo "starting d"; d; exit $?)&
wait
}&&
{
echo "starting e"
e
}
問題は、b、c、d のいずれかが失敗すると、スクリプトが続行され、e が実行されることです。これを防ぐ方法はありますか?
どのような回答でも大いに感謝します!
アントワーヌ
答え1
{
(echo "starting b"; b)&
(echo "starting c"; c)&
(echo "starting d"; d)&
wait %1 && wait %2 && wait %3
}&&
特定のジョブを待機しているときにwait
このジョブの終了コードが返されます
理解するには、次の 2 つの例を見てください。
最後の行だけが重要です(の終了ステータスを表示しますwait
)
(sleep 3; false) & wait; echo $?
[1] 25358
[1]+ Exit 1 ( sleep 3; false )
0
--
(sleep 3; false) & wait %1; echo $?
[1] 25362
[1]+ Exit 1 ( sleep 3; false )
1
答え2
プロセスをバックグラウンドで実行することで、基本的に、プロセスの成功や失敗には関心がないことをシェルに伝えていることになります。
wait
意思該当する場合は、終了コードでシグナルの値を報告します。これは探しているものではありません。
解決策としては、各コマンドのステータスを stdout に報告し、grep を使用して応答をカウントすることが挙げられます。
{
(echo "starting b"; b && echo ok)&
(echo "starting c"; c && echo ok)&
(echo "starting d"; d && echo ok)&
} |
grep -c ok | ( read n && (( n==3 )) ) &&
{
echo "starting e"; e
}