Каковы минимальные и максимальные значения следующих кодов выхода в Linux:
- Код завершения, возвращаемый двоичным исполняемым файлом (например, программой на Си).
- Код выхода, возвращаемый скриптом bash (при вызове
exit
). - Код выхода, возвращаемый функцией (при вызове
return
). Я думаю, что это между0
и255
.
linux
executable
function
exit-status
user271801
источник
источник
return
, Конечно же , встроенная команда оболочки.bash
оболочки. Некоторые другие оболочки вродеzsh
могут возвращать любое 32-битное значение со знаком, например, дляexit
. Некоторые любятrc
илиes
могут возвращать данные любого из поддерживаемых ими типов (скаляр или список). Смотрите связанные вопросы и ответы для деталей.Ответы:
Номер передается
_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()
inC
, libc вызывает этот системный вызов с возвращаемым значением.Большинство языков имеют
exit()
функцию, которая переносит этот системный вызов, и значение, которое они принимают, если оно вообще передается системному вызову. (обратите внимание, что они обычно делают больше вещей, таких как очистка, выполняемаяexit()
функцией C, которая очищает буферы stdio, запускаетatexit()
ловушки ...)Это случай по крайней мере:
Иногда вы видите, что жалуются, когда вы используете значение за пределами 0-255:
Некоторые оболочки жалуются, когда вы используете отрицательное значение:
POSIX оставляет поведение неопределенным, если значение, переданное
exit
специальной встроенной функции, находится вне 0-> 255.Некоторые оболочки показывают неожиданное поведение, если вы делаете:
bash
(иmksh
неpdksh
на чем он основан) берет на себя усечение значения до 8 бит:Так что в этих оболочках, если вы хотите выйти со значением вне 0-255, вы должны сделать что-то вроде:
То есть выполните в этом же процессе другую команду, которая может вызвать системный вызов со значением, которое вы хотите.
как упоминалось в этом другом Q & A,
ksh93
имеет самое странное поведение для значений выхода от 257 до 256 + max_signal_number, где вместо вызоваexit_group()
он убивает себя соответствующим сигналом¹.и иначе усекает число как
bash
/mksh
.Likely Это, вероятно, изменится в следующей версии. Теперь, когда разработка
ksh93
была предпринята как усилие сообщества за пределами AT & T, это поведение, хотя и поощряемое каким-либо образом POSIX, возвращаетсяисточник
si_status
для Linux?int
не менее 16 бит, POSIX более или менее требует, чтобы он был не менее 32 бит, а среда программирования должна иметь uint32_t . Я не знаю, поддерживает ли Linux какую-либо среду программирования, где целые числа - это не 32 биты, я никогда не сталкивался с такой.Минимум есть
0
, и это считается значением успеха. Все остальные неудачи. Максимум255
также известен как-1
.Эти правила применяются как для скриптов, так и для других исполняемых файлов, а также для функций оболочки.
Большие значения приводят к модулю 256.
источник
bash
других или наиболее часто используемых) код завершения, передаваемый воexit
встроенный модуль, не обрабатывается по модулю 256, а вместо этого вызывает ошибку. (Например, общееexit -1
на самом деле не является переносимым эквивалентомexit 255
в большинстве оболочек). И то,exit(-1)
эквивалентен ли уровень C, являетсяexit(255)
деталью, которая де-факто наверняка будет работать, но зависит от поведения, определенного реализацией (хотя это не проблема для современных систем, которые вы, вероятно, будете использовать на практике).exit(1)
параметр до 8 бит.Это выглядит так просто, но о горе.
Язык C (и, следовательно, большинство других языков прямо или косвенно) требует, чтобы возвращение из from
main
было эквивалентно вызовуexit
с тем же аргументом, что и возвращаемое значение. Это целое число (тип возвращаемого очень четкоint
), так что в принципе диапазон будетINT_MIN
вINT_MAX
.Тем не менее, POSIX заявляет, что только самые младшие 8 передаваемых битов
exit
должны быть доступны ожидающему родительскому процессу, буквально, как если бы это было «status & 0xFF» .Таким образом, на практике код выхода - это (все еще подписанное) целое число, из которых установлены только самые младшие 8 битов.
Минимум при этом будет -128, а максимум 127. Погоди, это не правда. Это будет от 0 до 255.Но, увы, конечно, не все так просто . На практике Linux (точнее, bash) делает это по-другому . Допустимый диапазон кодов возврата - от 0 до 255 (т. Е. Без знака).
Чтобы быть в безопасности во избежание путаницы, вероятно, будет хорошей идеей просто предположить, что коды возврата не подписаны, и привести все, что вы получили,
wait
к беззнаковым. Таким образом, это согласуется с тем, что вы видите в оболочке. Поскольку самые верхние биты (включая самый старший) очищаются, это даже не «неправильно», потому что, хотя технически они подписаны, фактические значения всегда являются беззнаковыми (поскольку бит знака никогда не устанавливается).Это также помогает избежать распространенной ошибки сравнения кода выхода
-1
, с которой по какой-то странной причине, кажется, никогда не появляется, даже когда программа завершает работу-1
(ну, угадайте почему!).О вашем последнем пункте, возвращающемся из функции, если эта функция оказывается
main
, то смотрите выше. В противном случае это зависит от типа возвращаемого значения функции, в принципе это может быть что угодно (в том числеvoid
).источник
waitid()
представили.waitid()
делает то же самое, немного по-другому. Он ожидает определенного идентификатора или какого-либо потока и записывает результаты в указаннуюsiginfo_t
структуру, гдеsi_status
естьint
(так что ... со знаком , точно так же). Тем не менее,exit()
только проходит самые нижние 8 бит, так что ... абсолютно то же самое под капотом.exit()
передает все 32 бита параметра в ядро иwaitid()
возвращает все 32 бита из кода выхода. Может быть, вы проверили на Linux, где никто не хочет исправлять ошибки. Если вы мне не верите, проверьте это на POSIX-совместимой ОС ...exit
, в частности, вторую строку под заголовком «Описание», в которой говорится: «хотя только младшие 8 битов (то есть статус и 0377) должны быть доступны ожидающему родительскому процессу " . Вот как работает соответствующая реализация - 8 младших битов, а не 32. Есть ли у вас ссылка на 32 передаваемых бита?waitid()
иsiginfo_t
структура, передаваемаяSIGCHLD
обработчику, возвращается все 32 бита отexit()
параметра.Коды выхода из любого процесса - будь то двоичный исполняемый файл, сценарий оболочки или что-то еще - варьируются от 0 до 255. Можно передать большее значение
exit()
, но только 8 младших битов состояния доступны для другие процессы черезwait()
.Функция AC может быть объявлена как возвращающая почти любой тип. Пределы его возвращаемого значения полностью определяются этим типом: например, от -128 до 127 для возвращаемой функции
signed char
, от 0 до 4,2 миллиарда для возвращаемой функцииunsigned int
или любое число с плавающей запятой вплоть до и включаяinf
возвращаемую функциюdouble
. И это не считая нечисловых типов, таких какvoid *
илиstruct
...источник