Con bash
, tendrá esa garantía a menos que haya comenzado otro trabajo en segundo plano (y tenga en cuenta que los trabajos en segundo plano pueden iniciarse &
pero también con coproc
y con la sustitución de procesos) entre el foo &
y el wait
.
POSIX requiere que un shell recuerde el estado de salida de al menos 25 trabajos después de que se hayan ido , pero bash
recuerda mucho más que eso.
Ahora, si lo haces:
foo & pid=$!
...
bar &
wait "$pid"
No tiene ninguna garantía de que bar
no se le dará el mismo pid que foo
(si foo
ha terminado antes de que bar
comience), por lo que, aunque es poco probable, wait "$pid"
puede darle el estado de salida de bar
.
Puedes reproducirlo con:
bash -c '(exit 12; foo) & pid=$!
while : bar & [ "$pid" != "$!" ]; do :;done
wait "$pid"; echo "$?"'
que (eventualmente) te dará en 0
lugar de 12
.
Para evitar el problema, una forma sería escribirlo 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
no funciona. El proceso se recopila y el estado de salida se descarta justo antes de que se muestre la solicitud (de forma predeterminada).