次のコードを検討してください。
job()
{
local id=$1
sleep $id
}
do_job_in_parallel()
{
local pids=()
# run subshells
for id in $(seq 4)
do
job $id &
pids=("${pids[@]}" $!)
done
# wait subshells
for ((i=0; i<${#pids[@]}; ++i))
do
local pid=${pids[$i]}
wait $pid
exit_status=$?
if [[ $exit_status -ne 0 ]]
then
echo "job with pid $pid failed with exit status $exit_status"
#TODO: kill all subshells
fi
done
}
「サブシェルが1つでも失敗すると、すべてのサブシェルが失敗します」というロジックを実装する必要があると思います。 X と Y の待機が順次実行される場合 (上記のコードを参照)、たとえば、X を待っている間に Y が失敗した場合に待機する必要はありません。より正確には、「サブシェルが失敗した場合に他のすべてのサブシェルをすぐにシャットダウンする」方法を実装する方法は何ですか?
答え1
forループに対する簡単な解決策はないと思いますwait
が、GNU Parallel(https://www.gnu.org/software/parallel/)これのために。お気に入りのパッケージマネージャから配布できる必要があります。
#!/bin/bash
#
do_job()
{
local id=$1
sleep $id
}
export -f do_job
do_job_in_parallel()
{
parallel --halt now,done=1 do_job "{}" ::: $(seq 4)
}
do_job_in_parallel
"now,done=1"に加えて、他のオプションがあります。新しいジョブの開始を停止するsoon
のではなく、進行中のプロセスを正常に終了させ、プロセスがゼロで終了した場合にのみ停止し、そうでない場合にのみ停止するように指定できます。ジョブの数や割合など、すべての詳細はドキュメントにあります。now
success=1
fail=1
https://www.gnu.org/software/parallel/parallel.html。