Procesy mogą wywoływać wywołanie _exit()systemowe (w systemie Linux, patrz także exit_group()) z argumentem liczby całkowitej, aby zgłosić kod wyjścia do ich rodzica. Chociaż jest to liczba całkowita, tylko 8 najmniej znaczących bitów jest dostępnych dla rodzica (wyjątek stanowi to podczas używania waitid()lub obsługi SIGCHLD w rodzicu w celu pobrania tego kodu , choć nie w Linuksie).
Rodzic zwykle robi a wait()lub, waitpid()aby uzyskać status swojego dziecka jako liczbę całkowitą (chociaż waitid()można użyć również nieco innej semantyki).
W systemie Linux i większości Uniksów, jeśli proces zakończy się normalnie, bity od 8 do 15 tego numeru statusu będą zawierały kod wyjścia, który został przekazany exit(). Jeśli nie, to 7 najmniej znaczących bitów (od 0 do 6) będzie zawierało numer sygnału, a bit 7 zostanie ustawiony, jeśli rdzeń został zrzucony.
perljest $?, na przykład, że zawiera szereg określonych przez waitpid():
$ perl -e 'system q(kill $$); printf "%04x\n", $?'
000f # killed by signal 15
$ perl -e 'system q(kill -ILL $$); printf "%04x\n", $?'
0084 # killed by signal 4 and core dumped
$ perl -e 'system q(exit $((0xabc))); printf "%04x\n", $?'
bc00 # terminated normally, 0xbc the lowest 8 bits of the status
Powłoki podobne do Bourne'a również ustawiają status wyjścia ostatniego polecenia uruchomienia we własnej $?zmiennej. Jednak nie zawiera bezpośrednio liczby zwróconej przez waitpid(), ale transformację i różni się między powłokami.
Wspólne dla wszystkich powłok jest to, że $?zawiera najmniej 8 bitów kodu wyjścia (liczby przekazanej do exit()), jeśli proces zakończy się normalnie.
Różni się to, gdy proces kończy się sygnałem. We wszystkich przypadkach, a jest to wymagane przez POSIX, liczba będzie większa niż 128. POSIX nie określa, jaka może być wartość. W praktyce jednak we wszystkich znanych mi powłokach Bourne'a 7 najniższych bitów $?będzie zawierało liczbę sygnałów. Ale gdzie njest numer sygnału,
w ash, zsh, pdksh, bash, powłoka Bourne'a $?jest 128 + n. Co to znaczy, że w tych pocisków, jeśli masz $?z 129, nie wiem, czy to dlatego, że proces zakończył działanie exit(129), czy też został zabity sygnałem 1( HUPw większości systemów). Ale uzasadnieniem jest to, że powłoki, gdy same się kończą, domyślnie zwracają status wyjścia ostatnio zakończonej komendy. Upewniając się, że $?nigdy nie jest większy niż 255, pozwala to uzyskać spójny status wyjścia:
$ bash -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
bash: line 1: 16720 Terminated sh -c "kill \$\$"
8f # 128 + 15
$ bash -c 'sh -c "kill \$\$"; exit'; printf '%x\n' "$?"
bash: line 1: 16726 Terminated sh -c "kill \$\$"
8f # here that 0x8f is from a exit(143) done by bash. Though it's
# not from a killed process, that does tell us that probably
# something was killed by a SIGTERM
ksh93, $?jest 256 + n. Oznacza to, że od wartości $?możesz rozróżnić proces zabity i nie zabity. Nowsze wersje ksh, przy wyjściu, jeśli $?były większe niż 255, zabijają się tym samym sygnałem, aby móc zgłosić ten sam status wyjścia rodzicowi. Chociaż wydaje się to dobrym pomysłem, oznacza to, że kshwygeneruje dodatkowy zrzut rdzenia (potencjalnie nadpisujący drugi), jeśli proces zostanie zabity przez sygnał generujący rdzeń:
$ ksh -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
ksh: 16828: Terminated
10f # 256 + 15
$ ksh -c 'sh -c "kill -ILL \$\$"; exit'; printf '%x\n' "$?"
ksh: 16816: Illegal instruction(coredump)
Illegal instruction(coredump)
104 # 256 + 15, ksh did indeed kill itself so as to report the same
# exit status as sh. Older versions of `ksh93` would have returned
# 4 instead.
Można nawet powiedzieć, że jest błąd, który ksh93zabija się, nawet jeśli $?pochodzi od funkcji return 257wykonanej przez:
$ ksh -c 'f() { return "$1"; }; f 257; exit'
zsh: hangup ksh -c 'f() { return "$1"; }; f 257; exit'
# ksh kills itself with a SIGHUP so as to report a 257 exit status
# to its parent
yash. yashoferuje kompromis. Powraca 256 + 128 + n. Oznacza to, że możemy również odróżnić zabity proces od tego, który zakończył się prawidłowo. A po wyjściu zgłosi się 128 + nbez samobójstwa i skutków ubocznych, jakie może mieć.
$ yash -c 'sh -c "kill \$\$"; printf "%x\n" "$?"'
18f # 256 + 128 + 15
$ yash -c 'sh -c "kill \$\$"; exit'; printf '%x\n' "$?"
8f # that's from a exit(143), yash was not killed
Aby uzyskać sygnał z wartości $?, przenośnym sposobem jest użycie kill -l:
$ /bin/kill 0
Terminated
$ kill -l "$?"
TERM
(ze względu na przenośność nigdy nie należy używać numerów sygnałów, a jedynie nazw sygnałów)
Na frontach innych niż Bourne:
csh/ tcshi to fishsamo co powłoka Bourne'a, z tym wyjątkiem, że status jest $statuszamiast $?(należy pamiętać, że zshustawia się również $statusdla zgodności z csh(oprócz $?)).
rc: status wyjścia $statusrównież jest, ale gdy zabije go sygnał, zmienna ta zawiera nazwę sygnału (jak sigtermlub sigill+corejeśli rdzeń został wygenerowany) zamiast liczby, co jest kolejnym dowodem dobrego projektu tej powłoki .
es. status wyjścia nie jest zmienną. Jeśli zależy Ci na tym, uruchom polecenie jako:
status = <={cmd}
która zwróci liczbę sigtermlub sigsegv+corejak w rc.
Może pod względem kompletności, powinniśmy wspomnieć zsh„s $pipestatusi bash” s $PIPESTATUStablice, które zawierają kod zakończenia elementów ostatniej rurociągu.
A także dla kompletności, jeśli chodzi o funkcje powłoki i pliki źródłowe, domyślnie funkcje zwracają ze statusem zakończenia ostatniego uruchomienia polecenia, ale mogą również ustawić jawnie status powrotu za pomocą returnwbudowanego. Widzimy tutaj pewne różnice:
bashi mksh(od R41 regresja ^ Witch najwyraźniej wprowadzona umyślnie ) skróci liczbę (dodatnią lub ujemną) do 8 bitów. Na przykład return 1234ustawimy $?na 210, return -- -1ustawimy $?na 255.
zshoraz pdksh(i pochodne inne niż mksh) pozwalają na każdą 32-bitową liczbę całkowitą ze znakiem (-2 31 do 2 31 -1) (i skracają liczbę do 32 bitów ).
ashi yashzezwól na dowolną liczbę całkowitą dodatnią od 0 do 2 31 -1 i zwróć błąd dla dowolnej liczby z tego.
ksh93w return 0celu return 320ustawienia $?w takim stanie, ale nic innego, obcina do 8 bitów. Uważaj, jak już wspomniano, że zwrócenie liczby między 256 a 320 może spowodować kshsamobójstwo przy wyjściu.
rci eszezwalaj na zwracanie dowolnych nawet list
Należy również pamiętać, że niektóre powłoki również użyć specjalnych wartości $?/ $statuszgłosić pewne warunki błędów, które nie są kod zakończenia procesu, jak 127i 126na polecenie nie znaleziono lub nie wykonywalny (lub błąd składni w pliku) pochodzących ...
killall myScriptprace, stąd zwrócenie killall (a nie skryptu!) wynosi 0. Możesz umieścićkill -x $$[x będący liczbą sygnału, a $$ zwykle rozszerzane przez powłokę do PID tego skryptu (działa w sh, bash, ...)] w skrypcie, a następnie przetestuj, jaki był jego rdzeń wyjściowy.