Dzięki bash
nie będziesz mieć takiej gwarancji, chyba że rozpoczniesz inne zadanie w tle (i strzeż się, że zadania w tle można uruchamiać z, &
ale także z coproc
i z zastępowaniem procesów) między foo &
i wait
.
POSIX wymaga, aby powłoka zapamiętała status wyjścia z co najmniej 25 zadań po ich odejściu , ale bash
pamięta o wiele więcej.
Teraz, jeśli to zrobisz:
foo & pid=$!
...
bar &
wait "$pid"
Nie masz żadnej gwarancji, że bar
nie otrzymasz tego samego pid jak foo
(jeśli foo
wygasł przed czasem bar
), więc nawet jeśli jest mało prawdopodobne, wait "$pid"
może dać ci status wyjścia bar
.
Możesz go odtworzyć za pomocą:
bash -c '(exit 12; foo) & pid=$!
while : bar & [ "$pid" != "$!" ]; do :;done
wait "$pid"; echo "$?"'
które (ostatecznie) dadzą ci 0
zamiast 12
.
Aby uniknąć problemu, jednym ze sposobów byłoby napisanie go jako:
{
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
nie działa. Proces jest gromadzony, a status wyjścia odrzucany tuż przed wyświetleniem monitu (domyślnie).wait %1
Nie powiedzie się z „braku takiej pracy” jako proces w tle są zbierane bezpośrednio po „5” dopełnia sen.%1
zamiast$!
.bash -c '(sleep 1;exit 5) & sleep 2; wait %1; echo $?'
(także nieinteraktywne) nie uzyskuje statusu wyjścia z tej martwej pracy. Brzmi jak błąd.set +e
. Wygląda na to, żeset -e
funkcja bash zabija skrypt, gdy tylko zostanie zgłoszony zły kod wyjściawait
Uważam, że twoje założenie jest prawidłowe. Oto fragment
man bash
dotyczący oczekiwania na procesy w tle.Więc może powinieneś sprawdzić 127
Jest podobne pytanie z zupełnie inną odpowiedzią, niż mogłoby pomóc.
Skrypt Bash czeka na procesy i otrzymuje kod powrotu
edycja 1
Zainspirowany komentarzami i odpowiedziami @ Stephane'a rozszerzyłem jego skrypt. Mogę rozpocząć około 34 procesów w tle, zanim zacznie tracić orientację.
tback
w moim systemie produkuje
źródło
bash -c '(exit 12) & sleep 1; wait "$!"; echo "$?"'
bash
luźnego toru (nawet po rozpoczęciu tysięcy prac), mój przykład demonstrował ponowne użycie pid, co może być również tym, co zaobserwowałeś w twoim przypadku.