Onde / quando os status de saída são retornados para trabalhos em segundo plano no bash?

3

Eu estou escrevendo um script que tem muitas partes, mas eu quero construir resiliência e processamento paralelo, tanto quanto possível. Um exemplo está abaixo:

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

Gostaria de executar os 3 comandos curl em paralelo, e depois os três comandos "faça algo" em paralelo também. No entanto, não tenho certeza de como isso seria tratado. Considerei inserir o comando wait após cada bloco e inserir & após cada comando da seguinte forma:

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

No entanto, nesta situação, não sei como os status de saída e / ou condições de corrida podem ser gerenciados. Além disso, isso não parece ser a melhor prática de codificação. Existe uma boa maneira de fazer isso?

    
por Teofrostus 22.10.2015 / 21:59

1 resposta

2

O Bash não permite capturar a saída de algo em segundo plano.

$ 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 -n , que retorna quando algum processo em segundo plano terminou, e sai com o status de saída desse processo. Como você sabe quantos processos em segundo plano você tem, você pode wait -n tantas vezes. Feio, mas ...

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
    
por 22.10.2015 / 23:24