С 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
не работает. Процесс собирается и состояние выхода сбрасывается непосредственно перед отображением приглашения (по умолчанию).wait %1
Терпит неудачу с «нет такой работы» , как фоновый процесс собирается сразу после «сна 5» завершается.%1
вместо$!
.bash -c '(sleep 1;exit 5) & sleep 2; wait %1; echo $?'
(так что неинтерактивно) не удается получить статус завершения этого мертвого задания. Похоже, ошибка.set +e
. Похоже, чтоset -e
функция bash убивает скрипт, как только неправильный код выхода вызывается пользователемwait
Я считаю, что ваше предположение верно. Вот выдержка из
man bash
ожидания фоновых процессов.Так что, возможно, вы должны проверить на 127
Есть похожий вопрос с совершенно другим ответом, чем может помочь.
Bash скрипт ждет процессов и получает код возврата
редактировать 1
Вдохновленный комментариями и ответами @ Stephane, я расширил его сценарий. Я могу запустить около 34 фоновых процессов до того, как они начнут терять свой след
tback
на моей системе выдает
источник
bash -c '(exit 12) & sleep 1; wait "$!"; echo "$?"'
bash
треков (даже после запуска тысяч рабочих мест), мой пример демонстрировал повторное использование pid, что может быть тем, что вы наблюдали и в вашем случае.