Numer przekazywany do wywołania systemowego _exit()
/ exit_group()
(czasami nazywany kodem wyjścia, aby uniknąć niejednoznaczności ze statusem wyjścia, który odnosi się również do kodowania kodu wyjścia lub numeru sygnału i dodatkowych informacji w zależności od tego, czy proces został zabity, czy zakończony normalnie ) jest typu int
, więc w systemach uniksopodobnych, takich jak Linux, zwykle jest to 32-bitowa liczba całkowita o wartościach od -2147483648 (-2 31 ) do 2147483647 (2 31 -1).
Jednak we wszystkich systemach, kiedy proces nadrzędny (lub subreaper dziecko lub init
jeśli rodzic zmarł) używa wait()
, waitpid()
, wait3()
, wait4()
wywołania systemowe, aby je odzyskać, tylko dolne 8 bitów to są dostępne (wartości od 0 do 255 (2 8 - 1)).
Podczas korzystania z waitid()
interfejsu API (lub procedury obsługi sygnału w SIGCHLD) w większości systemów (a ponieważ POSIX bardziej wyraźnie wymaga tego w wersji standardowej 2016 (patrz _exit()
specyfikacja )) dostępna jest pełna liczba (w si_status
polu zwracanej struktury ). Nie jest tak jednak w przypadku Linuksa, który również zmniejsza liczbę waitid()
interfejsów API do 8 bitów , choć może się to zmienić w przyszłości.
Ogólnie rzecz biorąc, chciałbyś używać tylko wartości 0 (ogólnie oznacza sukces) tylko do 125, ponieważ wiele powłok używa wartości powyżej 128 w ich $?
reprezentacji statusu wyjścia do zakodowania numeru sygnału zabijanego procesu oraz 126 i 127 dla specjalnych warunki.
Możesz użyć 126 do 255, exit()
aby oznaczać to samo, co w przypadku powłoki $?
(tak jak w przypadku skryptu ret=$?; ...; exit "$ret"
). Używanie wartości spoza 0 -> 255 na ogół nie jest przydatne. Zasadniczo zrobiłbyś to tylko wtedy, gdy wiesz, że rodzic użyje waitid()
interfejsu API w systemach, które nie są obcinane, a zdarza się, że potrzebujesz 32-bitowego zakresu wartości. Pamiętaj, że jeśli wykonasz exit(2048)
np., Rodzice będą postrzegać to jako sukces przy użyciu tradycyjnych wait*()
interfejsów API.
Więcej informacji na:
Mam nadzieję, że pytania i odpowiedzi powinny odpowiedzieć na większość pozostałych pytań i wyjaśnić, co oznacza status wyjścia . Dodam jeszcze kilka rzeczy:
Proces nie może zostać zakończony, dopóki nie zostanie zabity lub nie wywoła wywołań _exit()
/ exit_group()
system. Po powrocie z main()
w C
, zaproszeń libc tego wywołania systemowego z wartości zwracanej.
Większość języków ma exit()
funkcję, która otacza to wywołanie systemowe, oraz wartość, którą przyjmują, jeśli są one generalnie przekazywane tak samo jak wywołanie systemowe. (zauważ, że generalnie robią więcej rzeczy, takich jak czyszczenie wykonane przez exit()
funkcję C, która opróżnia bufory stdio, uruchamia atexit()
haki ...)
Tak jest w przypadku co najmniej:
$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234) = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234) = ?
$ strace -e exit_group perl -e 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234) = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234) = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234) = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)
Czasami widzisz osoby, które narzekają, gdy używasz wartości spoza 0-255:
$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1) = ?
Niektóre pociski skarżą się, gdy użyjesz wartości ujemnej:
$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2) = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2) = ?
POSIX pozostawia zachowanie niezdefiniowane, jeśli wartość przekazana do exit
specjalnego wbudowanego kodu jest poza 0-> 255.
Niektóre powłoki wykazują pewne nieoczekiwane zachowania, jeśli:
bash
( mksh
ale nie pdksh
na którym się opiera) bierze na siebie obcinanie wartości do 8 bitów:
$ strace -e exit_group bash -c 'exit 1234'
exit_group(210) = ?
Więc w tych powłokach, jeśli chcesz wyjść z wartością spoza 0-255, musisz zrobić coś takiego:
exec zsh -c 'exit -- -12345'
exec perl -e 'exit(-12345)'
To jest wykonanie innej komendy w tym samym procesie, która może wywołać wywołanie systemowe o żądanej wartości.
jak wspomniano w innych ksh93
pytaniach i odpowiedziach, ma najdziwniejsze zachowanie dla wartości wyjściowych od 257 do 256 + max_signal_number gdzie zamiast wywoływać exit_group()
, zabija się odpowiednim sygnałem¹.
$ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
zsh: suspended (signal) ksh -c 'exit "$((256 + $(kill -l STOP)))"'
i inaczej obcina liczbę, np . bash
/ mksh
.
¹ Prawdopodobnie zmieni się to w następnej wersji. Teraz, gdy rozwój ksh93
został przejęty jako wysiłek społeczności poza AT&T, zachowanie to, choć w jakiś sposób wspierane przez POSIX, zostaje cofnięte
return
To oczywiście wbudowana powłoka.