Com bash
, você terá essa garantia, a menos que tenha iniciado outro trabalho em segundo plano (e tenha cuidado para que os trabalhos em segundo plano possam ser iniciados, &
mas também com coproc
e com a substituição do processo) entre o foo &
e o wait
.
O POSIX exige que um shell se lembre do status de saída de pelo menos 25 trabalhos depois que eles saem , mas se bash
lembra muito mais do que isso.
Agora, se você fizer:
foo & pid=$!
...
bar &
wait "$pid"
Você não tem garantia de que bar
não receberá o mesmo pid que foo
(se foo
tiver terminado quando o horário bar
começar), portanto, mesmo que seja improvável, wait "$pid"
poderá fornecer o status de saída de bar
.
Você pode reproduzi-lo com:
bash -c '(exit 12; foo) & pid=$!
while : bar & [ "$pid" != "$!" ]; do :;done
wait "$pid"; echo "$?"'
que (eventualmente) lhe dará em 0
vez de 12
.
Para evitar o problema, uma maneira seria escrevê-lo como:
{
foo_pid=$!
while ps -p "$foo_pid"
do
ping -c 1 localhost
done
bar &
...
read <&3 ret
if [ "$ret" = 0 ]; then
echo foo was sucessful.
fi
} 3< <(foo > logfile 2>&1; echo "$?")
wait
não funciona. O processo é coletado e o status de saída descartado logo antes do prompt ser exibido (por padrão).wait %1
falha falha com "nenhum trabalho", pois o processo em segundo plano é coletado imediatamente após a conclusão do "sono 5".%1
no lugar de$!
.bash -c '(sleep 1;exit 5) & sleep 2; wait %1; echo $?'
(também não interativo) falha ao obter o status de saída desse trabalho morto. Parece um bug.Eu acredito que sua suposição está correta. Aqui está um extrato
man bash
sobre a espera de processos em segundo plano.Então talvez você deva procurar 127
Há uma pergunta semelhante com uma resposta completamente diferente do que poderia ajudar.
Script Bash aguarde processos e obtenha código de retorno
editar 1
Inspirado nos comentários e respostas de @ Stephane, expandi seu script. Posso iniciar cerca de 34 processos em segundo plano antes de começar a perder o controle.
tback
no meu sistema produz
fonte
bash -c '(exit 12) & sleep 1; wait "$!"; echo "$?"'
bash
uma pista solta (mesmo depois de iniciar milhares de empregos), meu exemplo foi demonstrar a reutilização do pid, que também pode ser o que você observou no seu caso.