Bash:サブシェルが失敗したことをどうやって確認しますか?

Bash:サブシェルが失敗したことをどうやって確認しますか?

次のコードを検討してください。

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のではなく、進行中のプロセスを正常に終了させ、プロセスがゼロで終了した場合にのみ停止し、そうでない場合にのみ停止するように指定できます。ジョブの数や割合など、すべての詳細はドキュメントにあります。nowsuccess=1fail=1https://www.gnu.org/software/parallel/parallel.html

関連情報