Como outros já disseram, não há como esperar "não" um ID de processo. No entanto, esse padrão de código não parece tão ruim para mim, então ofereço isso como uma maneira sugerida de conseguir o que você procura.
Ele faz uso de matrizes Bash, que você pode fornecer como uma lista para o comando wait
.
Exemplo
Uma versão modificada do seu código de exemplo, cmd.bash
.
!/bin/bash
array[0]=1
array[0]=2
sleep 30 &
pid=$!
pidArr=()
for i in ${array[@]}; do
for n in $(seq 3); do
if [ $n -eq 1 ]; then
sleep 31 > file &
pidArr+=($!)
else
sleep 32 >> file &
pidArr+=($!)
fi
done
done
echo ${pidArr[@]}
Eu substituí os comandos sleep
neste exemplo apenas para simular alguns trabalhos longos que podemos usar em segundo plano. Eles não têm nada a ver com isso além de agir como substitutos.
O comando final echo
também está disponível para que possamos ver o que acontece quando os loops for completos. Por fim, vamos substituí-lo por um comando wait
real, mas não vamos nos antecipar.
Exemplo de corrida nº 1
Então, vamos executar nosso programa e ver o que acontece.
$ ./cmd.bash
24666 24667 24668
Agora, se verificarmos ps
:
$ ps -eaf|grep sleep
saml 24664 1 0 22:28 pts/9 00:00:00 sleep 30
saml 24666 1 0 22:28 pts/9 00:00:00 sleep 31
saml 24667 1 0 22:28 pts/9 00:00:00 sleep 32
saml 24668 1 0 22:28 pts/9 00:00:00 sleep 32
Se esperarmos um pouco, estes acabarão por terminar. Mas isso mostra que, se adicionarmos os IDs do processo a um array, poderemos echo
-los depois.
Exemplo # 2
Então, vamos alterar esse echo
line out e trocar em uma linha wait
agora, algo assim:
wait ${pidArr[@]}
Agora, quando executamos nossa versão modificada, vemos que ela está aguardando TODOS os IDs do processo:
$ ./cmd.bash
... após ~ 30 segundos passa
$
Voltamos ao nosso aviso. Então, esperamos com sucesso por todos os processos. Uma rápida verificação de ps
:
$ ps -eaf|grep sleep
$
Então funcionou.