With bash
, you'll have that guarantee unless you've started another background job (and beware that background jobs can be started with &
but also with coproc
and with process substitution) between the foo &
and the wait
.
POSIX requires that a shell remembers the exit status of at least 25 jobs after they're gone, but bash
remembers a lot more than that.
Now, if you do:
foo & pid=$!
...
bar &
wait "$pid"
You've got no guarantee that bar
will not be given the same pid as foo
(if foo
has terminated by the time bar
starts), so even though it's unlikely, wait "$pid"
may give you the exit status of bar
.
You can reproduce it with:
bash -c '(exit 12; foo) & pid=$!
while : bar & [ "$pid" != "$!" ]; do :;done
wait "$pid"; echo "$?"'
which will (eventually) give you 0
instead of 12
.
To avoid the problem, one way would be to write it as:
{
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 "$?")
bash -c '(exit 12) & sleep 1; wait "$!"; echo "$?"'
– Stéphane Chazelas Feb 20 '14 at 14:19bash
loose track (even after starting thousands of jobs), my example was demonstrating the pid being reused, which may be what you observed in your case as well. – Stéphane Chazelas Feb 20 '14 at 20:21