考虑这段代码:
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
}
考虑到我们需要实现“如果任何子 shell 失败,则所有子 shell 失败”的逻辑。如果 X 和 Y 的等待是按顺序完成的(如上面的代码所示),并且例如,如果 Y 在等待 X 时失败,则无需等待 X。更准确地说,如何实现“如果任何子 shell 失败” ,然后立即杀死所有其他子 shell”?
答案1
我认为 for 循环没有一个简单的解决方案,wait
但你可以使用 GNU 并行(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
仅当进程以 0 退出时停止它们,fail=1
仅当以其他方式退出时,您可以指定一个数字或工作百分比等。所有详细信息都在文档中:https://www.gnu.org/software/parallel/parallel.html。