Bash:如何检查任何子shell是否失败?

Bash:如何检查任何子shell是否失败?

考虑这段代码:

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

相关内容