web-dev-qa-db-ja.com

bashのバックグラウンドジョブの終了ステータスはどこでいつ返されますか?

多くの部分からなるbashスクリプトを書いていますが、可能な限り復元力と並列処理を組み込みたいと思っています。例を以下に示します。

while true
do
  var=$(curl someurl) || continue
  var2=$(curl someurl2) || continue
  var3=$(curl someurl3) || continue
  dosomething var1 || continue
  dosomething2 var2 || continue
  dosomething3 var3 || continue
  break
done

3つのcurlコマンドを並行して実行してから、3つの「dosomething」コマンドも並行して実行したいと思います。ただし、これがどのように処理されるかはわかりません。次のように、各ブロックの後にwaitコマンドを挿入し、各コマンドの後に&を挿入することを検討しました。

while true
do
  var=$(curl someurl) & || continue
  var2=$(curl someurl2) & || continue
  var3=$(curl someurl3) & || continue
  wait
  dosomething var1 & || continue
  dosomething2 var2 & || continue
  dosomething3 var3 & || continue
  wait
  break
done

ただし、この状況では、終了ステータスや競合状態をどのように管理できるかわかりません。さらに、これはベストコーディングプラクティスのようには思えません。これを行う良い方法はありますか?

3
Teofrostus

Bashでは、バックグラウンドで何かの出力をキャプチャすることはできません。

$ unset var; var=$(sh -c 'sleep 5; echo foo; exit 42') 
$ echo $? $var 
42 foo
$ unset var; var=$(sh -c 'sleep 5; echo foo; exit 42') & wait
[1] 30250
[1]+  Exit 42                 var=$(sh -c 'sleep 5; echo foo; exit 42')
$ echo $? $var 
0 

有る wait -nsomeバックグラウンドプロセスが終了したときに返され、そのプロセスの終了ステータスで終了します。バックグラウンドプロセスの数がわかっているので、wait -n何度も。醜いですが...

while true
do
  curl someurl1 > file1 &
  curl someurl2 > file2 &
  curl someurl3 > file3 &
  for i in 1 2 3; do
    wait -n || { echo some curl failed; continue 2; }
  done

  dosomething "$(< file1)" &
  dosomething "$(< file2)" &
  dosomething "$(< file3)" &
  for i in 1 2 3; do
    wait -n || { echo some dosomething failed; continue 2; }
  done

  break
done
2
glenn jackman