С bash
этой гарантией у вас будет такая гарантия, если только вы не запустили другое фоновое задание (и помните, что фоновые задания можно запускать, &
но также coproc
и с заменой процесса) и между ними foo &
и wait
.
POSIX требует, чтобы оболочка запоминала состояние выхода как минимум из 25 заданий после того, как они ушли , но bash
запоминает гораздо больше.
Теперь, если вы делаете:
foo & pid=$!
...
bar &
wait "$pid"
У вас нет гарантии, что вам bar
не будет дан тот же pid, что и foo
(если foo
он был отменен к началу времени bar
), поэтому, даже если это маловероятно, он wait "$pid"
может дать вам статус выхода bar
.
Вы можете воспроизвести это с:
bash -c '(exit 12; foo) & pid=$!
while : bar & [ "$pid" != "$!" ]; do :;done
wait "$pid"; echo "$?"'
который (в конце концов) даст вам 0
вместо 12
.
Чтобы избежать этой проблемы, можно написать:
{
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
не работает. Процесс собирается и состояние выхода сбрасывается непосредственно перед отображением приглашения (по умолчанию).