Процессы могут вызывать _exit()
системный вызов (в Linux, см. Также exit_group()
) с целочисленным аргументом, чтобы сообщить код выхода своему родителю. Хотя это целое число, только 8 младших значащих битов доступны для родителя (исключение составляет использование waitid()
или обработка SIGCHLD в родительском объекте для получения этого кода , но не в Linux).
Родитель обычно делает wait()
или, waitpid()
чтобы получить статус своего потомка как целое число (хотя waitid()
может также использоваться несколько иная семантика).
В Linux и большинстве Unix, если процесс завершается нормально, биты 8–15 этого номера состояния будут содержать код завершения, как передано exit()
. Если нет, то 7 младших значащих битов (от 0 до 6) будут содержать номер сигнала, а бит 7 будет установлен, если ядро было сброшено.
perl
«ы $?
к примеру содержит это число , как установлено 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
Подобные Борну оболочки также делают состояние выхода последней команды запуска в своей собственной $?
переменной. Тем не менее, он не содержит непосредственно число, возвращаемое waitpid()
, но преобразование на него, и это отличается между оболочками.
Что общего между всеми оболочками, так это то, что они $?
содержат младшие 8 бит кода выхода (переданного числа exit()
), если процесс завершился нормально.
Отличие состоит в том, когда процесс завершается сигналом. Во всех случаях, и это требуется POSIX, число будет больше 128. POSIX не указывает, какое значение может быть. Однако на практике во всех известных мне борноподобных оболочках младшие 7 бит $?
будут содержать номер сигнала. Но где n
номер сигнала,
в золе, зш, пдкш, баш, скорлупа Борна, $?
есть 128 + n
. Что это означает, что в этих оболочках, если вы получаете $?
от 129
, вы не знаете , является ли это потому , что процесс завершился с exit(129)
или он был убит по сигналу 1
( HUP
в большинстве систем). Но логическое обоснование состоит в том, что оболочки, когда они действительно выходят из себя, по умолчанию возвращают статус завершения последней вышедшей команды. Удостоверьтесь, что $?
никогда не больше 255, что позволяет иметь постоянный статус выхода:
$ 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
, $?
Является 256 + n
. Это означает, что по значению $?
вы можете различить убитый и неубранный процесс. Более новые версии ksh
, при выходе, если $?
было больше 255, убивают себя тем же сигналом, чтобы иметь возможность сообщить об одном и том же статусе выхода его родителю. Хотя это звучит как хорошая идея, это означает, что ksh
будет генерироваться дополнительный дамп ядра (возможно, с перезаписью другого), если процесс был убит сигналом генерации ядра:
$ 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.
Где можно даже сказать , что есть ошибка в том , что ksh93
убивает себя , даже если $?
исходит от return 257
сделано с помощью функции:
$ 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
, yash
предлагает компромисс. Это возвращается 256 + 128 + n
. Это означает, что мы также можем различать завершенный процесс и процесс, завершившийся должным образом. И после выхода он сообщит 128 + n
без необходимости самоубийства и побочных эффектов, которые он может иметь.
$ 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
Чтобы получить сигнал от значения $?
, переносимым способом является использование kill -l
:
$ /bin/kill 0
Terminated
$ kill -l "$?"
TERM
(для переносимости, вы никогда не должны использовать номера сигналов, только имена сигналов)
На не-борнских фронтах:
csh
/ tcsh
и то fish
же самое, что и оболочка Bourne, за исключением того, что $status
вместо нее указан статус $?
(обратите внимание, что zsh
также устанавливается $status
совместимость с csh
(в дополнение к $?
)).
rc
: состояние выхода также в $status
состоянии, но когда убито сигналом, эта переменная содержит имя сигнала (например, sigterm
или sigill+core
если ядро было сгенерировано) вместо числа, что является еще одним доказательством хорошего дизайна этой оболочки ,
es
, статус выхода не является переменной. Если вы заботитесь об этом, вы запускаете команду как:
status = <={cmd}
который вернет число или sigterm
или sigsegv+core
как в rc
.
Возможно, для полноты изложения, мы должны упомянуть массивы zsh
's' $pipestatus
и bash
's', $PIPESTATUS
которые содержат состояние выхода компонентов последнего конвейера.
А также для полноты, когда речь идет о функциях оболочки и исходных файлах, по умолчанию функции возвращаются со статусом завершения последнего запуска команды, но также могут явно задавать статус возврата с помощью return
встроенной функции. И мы видим некоторые различия здесь:
bash
и mksh
(начиная с R41, регрессия ^ Wchange, очевидно, введенная намеренно ) будет усекать число (положительное или отрицательное) до 8 бит. Так, например , return 1234
будет установлен $?
в 210
, return -- -1
будет установлено $?
255.
zsh
и pdksh
(и другие производные, кроме mksh
) разрешают любое 32-разрядное десятичное целое число со знаком (от -2 31 до 2 31 -1) (и сокращают число до 32 бит).
ash
и yash
разрешить любое положительное целое число от 0 до 2 31 -1 и вернуть ошибку для любого числа из этого.
ksh93
для того, return 0
чтобы return 320
установить $?
как есть, но для чего-то еще, усечь до 8 бит. Остерегайтесь, как уже упоминалось, возвращение числа от 256 до 320 может привести ksh
к самоубийству при выходе.
rc
и es
разрешить возвращать что угодно, даже списки.
Также обратите внимание, что некоторые оболочки также используют специальные значения $?
/, $status
чтобы сообщать о некоторых состояниях ошибки, которые не являются состоянием выхода процесса, например, 127
или 126
для команды, не найденной или не исполняемой (или синтаксическая ошибка в исходном файле) ...
killall myScript
работы, поэтому возвращение killall (а не сценария!) равно 0. Вы можете поместитьkill -x $$
[x, являющийся номером сигнала, и $$ обычно расширяется оболочкой до PID этого сценария (работает в sh, bash, ...)] внутри скрипта, а затем протестируйте ядро его выхода.