Номер, переданий в _exit()
/ exit_group()
системний виклик (іноді його називають кодом виходу, щоб уникнути неоднозначності зі статусом виходу, який також посилається на кодування або коду виходу, або номера сигналу та додаткової інформації залежно від того, процес був убитий чи вийшов нормально ) типу int
, тому для Unix-подібних систем, таких як Linux, як правило, це 32-бітове ціле число зі значеннями від -2147483648 (-2 31 ) до 2147483647 (2 31 -1).
Тим НЕ менше, на всі системи, коли (дитина subreaper або або батьківський процес , init
якщо батько помер) використовує wait()
, waitpid()
, wait3()
, wait4()
системні виклики , щоб отримати його, тільки молодші 8 біт нього є (значення від 0 до 255 (2 8 - 1)).
При використанні waitid()
API (або обробника сигналу на SIGCHLD), у більшості систем (і як POSIX зараз чіткіше вимагає у випуску стандарту 2016 року (див. _exit()
Специфікацію )) доступне повне число (у si_status
полі повернутої структури ). Це не так у Linux, хоча це також скорочує число до 8 біт за допомогою waitid()
API, хоча це, можливо, зміниться в майбутньому.
Як правило, ви хочете використовувати лише значення 0 (загалом означає успіх) лише до 125, оскільки багато оболонок використовують значення вище 128 у своєму $?
поданні про стан виходу, щоб кодувати номер сигналу процесу, що вбивається, та 126 та 127 для спеціальних умови.
Ви можете використовувати 126 до 255, exit()
щоб означати те саме, що вони роблять для оболонки $?
(наприклад, коли це робить сценарій ret=$?; ...; exit "$ret"
). Використання значень поза 0 -> 255, як правило, не корисно. Як правило, ви робите це лише в тому випадку, якщо ви знаєте, що батько використовуватиме waitid()
API в системах, які не скорочуються, і у вас виникає потреба в діапазоні значень 32 біт. Зверніть увагу, що якщо ви зробите, exit(2048)
наприклад, батьки вважатимуть це успіхом, використовуючи традиційні wait*()
API.
Більше інформації за адресою:
Сподіваємось, що ці запитання повинні відповісти на більшість ваших інших питань та уточнити, що означає статус виходу . Я додам ще кілька речей:
Процес не може закінчитися, якщо він не вбитий або не викликає _exit()
/ exit_group()
виклики системи. Коли ви повернетеся з main()
в C
, то Libc виклики цієї системи виклику з повертається значенням.
Більшість мов мають exit()
функцію, яка завершує системний виклик, і значення, яке вони приймають, якщо таке взагалі передається, як і системному виклику. (зауважте, що вони, як правило, роблять більше таких речей, як очищення, виконане за допомогою exit()
функції C, яка змиває буфери stdio, запускає atexit()
гачки ...)
Ось так щонайменше:
$ 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)
Ви час від часу бачите тих, хто скаржиться, коли ви використовуєте значення поза 0-255:
$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1) = ?
Деякі оболонки скаржаться, коли ви використовуєте негативне значення:
$ 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 залишає поведінку невизначеною, якщо значення, передане exit
спеціальному вбудованому, знаходиться поза 0-> 255.
Деякі снаряди демонструють деякі несподівані поведінки, якщо ви робите:
bash
( mksh
а не pdksh
на основі, на якій вона базується) бере на себе обрізати значення до 8 біт:
$ strace -e exit_group bash -c 'exit 1234'
exit_group(210) = ?
Тож у цих оболонках, якщо ви хочете вийти зі значенням поза 0-255, вам потрібно зробити щось на кшталт:
exec zsh -c 'exit -- -12345'
exec perl -e 'exit(-12345)'
Це виконати іншу команду в тому ж процесі, яка може викликати системний виклик із потрібним значенням.
як згадувалося в тому іншому запитанні та відповіді, ksh93
має найсмішнішу поведінку для значень виходу від 257 до 256 + max_signal_number, де замість виклику exit_group()
він вбиває себе відповідним сигналом¹.
$ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
zsh: suspended (signal) ksh -c 'exit "$((256 + $(kill -l STOP)))"'
і в іншому випадку скорочує число, як bash
/ mksh
.
Though Хоча це зміниться в наступній версії. Тепер, коли розвиток ksh93
було взято назустріч зусиллям спільноти поза AT&T, така поведінка, хоча POSIX якось заохочується, повертається.
return
. Звичайно, це вбудована оболонка.