Процессы могут вызывать _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, ...)] внутри скрипта, а затем протестируйте ядро его выхода.