Код выхода по умолчанию, когда процесс завершается?

Короче говоря: нет.

Необходимо будет восстановить от резервного копирования. (Некоторые резервные инструменты могли бы иметь опции только восстановить только разрешение, другие могут перечислить поддержанные файлы со своими полномочиями, и можно использовать это для фиксации системы.)

Если у Вас не будет резервного копирования, то необходимо будет зафиксировать все это вручную.

57
07.09.2016, 03:29
4 ответа

Процессы могут звонить _exit() системный вызов (на Linux, см. также exit_group()) с целочисленным аргументом для создания отчетов о коде выхода их родителю. Хотя это - целое число, только 8 младших значащих битов доступны родителю (исключение к этому при использовании waitid() или обработчик на SIGCHLD в родителе для получения того кода, хотя не на Linux).

Родитель будет обычно делать a wait() или waitpid() получить состояние их ребенка как целое число (хотя waitid() с несколько другой семантикой может использоваться также).

На Linux и большинстве Нельдов, если процесс обычно завершался, биты, 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 число сигнала,

  • в пепле, zsh, pdksh, ударе, Оболочке Bourne, $? 128 + n. То, что это означает, - то, что в тех оболочках, если Вы получаете a $? из 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 уничтожает себя даже если $? прибывает из a 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 $pipestatus и bash $PIPESTATUS массивы, которые содержат статус выхода компонентов последнего конвейера.

И также для полноты, когда дело доходит до функций оболочки и полученных файлов, возвратом функций по умолчанию со статусом выхода последней выполненной команды, но может также установить статус возврата явно с return встроенный. И мы видим некоторые различия здесь:

  • bash и mksh (так как R41, regression^Wchange, по-видимому, представленный намеренно), усечет число (положительный или отрицательный) к 8 битам. Так, например, return 1234 установит $? кому: 210, return -- -1 установит $? к 255.
  • zsh и pdksh (и производные кроме mksh) позвольте любой подписал десятичное целое число на 32 бита (-231 к 231-1) (и усеките число к 32 битам).
  • ash и yash позвольте любое положительное целое число от 0 до 231-1 и возвратите ошибку для любого числа из этого.
  • ksh93 для return 0 кому: return 320 набор $? как, но для чего-либо еще, усеченного к 8 битам. Остерегайтесь, как уже упомянуто, что возврат числа между 256 и 320 мог вызвать ksh уничтожить себя на выход.
  • rc и es позвольте возвращаться, что-либо даже перечисляет.

Также обратите внимание, что некоторые оболочки также используют специальные значения $?/$status сообщить о некоторых состояниях ошибки, которые не являются статусом выхода процесса, как 127 или 126 для команды, не найденной или не исполняемый файл (или синтаксическая ошибка в полученном файле)...

61
27.01.2020, 19:32
  • 1
    an exit code to their parent и to get the *status* of their child. Вы добавили акцент на "состояние". exit code и *status* то же? Случай да, каков источник наличия двух имен? Случай не то же, Вы могли дать определение/ссылку состояния? –  n611x007 23.06.2014, 12:18
  • 2
    Здесь существует 3 числа. Код выхода: число передало exit(). Статус выхода: число, полученное waitpid() который включает код выхода, число сигнала и было ли выведенное ядро. И число, которое некоторые оболочки делают доступными в одной из их специальных переменных ($?, $status) это - преобразование статуса выхода таким способом, который является, действительно содержит код выхода в случае, если было нормальное завершение, но также и несет сигнальную информацию, если процесс был уничтожен (что каждого также обычно называют статусом выхода). Это все объяснено в моем ответе. –  Stéphane Chazelas 23.06.2014, 12:46
  • 3
    я вижу спасибо! Я определенно ценю это явное примечание различия здесь. Эти выражения относительно выхода используются так попеременно в некоторых местах, стоит сделать его. Вариант переменной оболочки даже имеет (общее) имя? Таким образом, я предложил бы разрешить его явно прежде сообщающий подробности относительно оболочек. Я предложил бы вставить объяснение (из Вашего комментария) после Вашего первого или второго абзаца. –  n611x007 23.06.2014, 12:59
  • 4
    Можно ли указать на кавычку POSIX, которая говорит о первых 7 битах, являющихся сигналом? Все, что я мог найти, было > 128 часть: "О статусе выхода команды, которая завершилась, потому что он получил сигнал, нужно сообщить как больше, чем 128". pubs.opengroup.org/onlinepubs/9699919799/utilities / спасибо … –  Ciro Santilli 新疆改造中心法轮功六四事件 05.08.2015, 17:58

Когда процесс выходит, он возвращает целочисленное значение к операционной системе. На большинстве вариантов Unix это значение принято по модулю 256: все кроме битов младшего разряда проигнорировано. Состояние дочернего процесса возвращается к своему родителю через 16-разрядное целое число в который

  • биты 0–6 (7 битов младшего разряда) являются числом сигнала, которое использовалось для уничтожения процесса, или 0 если процесс, из которого выходят обычно;
  • бит 7 установлен, если процесс был уничтожен сигналом и вывел ядро;
  • биты 8–15 являются кодом выхода процесса, если процесс обычно выходил, или 0, если процесс был уничтожен сигналом.

Состояние возвращается wait системный вызов или один из его одноуровневых элементов. POSIX не указывает точное кодирование статуса выхода и сигнализирует о числе; это только обеспечивает

  • способ сказать, соответствует ли статус выхода сигналу или к нормальному выходу;
  • способ получить доступ к коду выхода, если процесс, из которого выходят обычно;
  • способ получить доступ к числу сигнала, если процесс был уничтожен сигналом.

Строго говоря нет никакого кода выхода, когда процесс уничтожается сигналом: что существует, вместо этого статус выхода.

В сценарии оболочки о статусе выхода команды сообщают через специальную переменную $?. Эта переменная кодирует статус выхода неоднозначным способом:

  • Если процесс, из которого выходят обычно затем $? его статус выхода.
  • Если процесс был уничтожен сигналом затем $? 128 плюс число сигнала в большинстве систем. POSIX только передает под мандат это $? больше, чем 128 в этом случае; ksh93 добавляет 256 вместо 128. Я никогда не видел вариант Unix, который сделал что-либо кроме, добавляет константа к числу сигнала.

Таким образом в сценарии оболочки Вы не можете сказать окончательно, была ли команда уничтожена сигналом или вышлась с кодом состояния, больше, чем 128, кроме с ksh93. Очень редко для программ выйти с кодами состояния, больше, чем 128, частично потому что программисты избегают его из-за $? неоднозначность.

SIGINT является сигналом 2 на большинстве вариантов Unix, таким образом $? 128+2=130 для процесса, который был уничтожен SIGINT. Вы будете видеть 129 для SIGHUP, 137 для SIGKILL, и т.д.

23
27.01.2020, 19:32
  • 1
    Намного лучше сформулированный и главный, чем мой, даже если это говорит в сущности то же самое. Можно хотеть разъяснить это $? для подобных Границе оболочек только.См. также yash для другого (но все еще POSIX) поведение. Также согласно POSIX+XSI (Unix), a kill -2 "$pid" отправит SIGINT в процесс, но фактическое число сигнала не может быть 2, таким образом, $? не обязательно не будет 128+2 (или 256+2 или 384+2), хотя kill -l "$?" возвратится INT, который является, почему я советовал бы для мобильности для не обращения к самим числам. –  Stéphane Chazelas 07.11.2013, 00:23

Это зависит от Вашей оболочки. От bash(1) страница справочника, раздел SHELL GRAMMAR, Простой подраздел Команд:

Возвращаемое значение простой команды [...] 128+n, если команда завершается сигналом n.

С тех пор SIGINT в Вашей системе сигнал номер 2, возвращаемое значение равняется 130, когда это выполняется под Bash.

9
27.01.2020, 19:32
  • 1
    Как в мире Вы находите это или даже знаете, где посмотреть? Я кланяюсь перед Вашим гением. –  Cory Klein 06.11.2013, 19:59
  • 2
    @CoryKlein: Опыт, главным образом. О, и Вы, вероятно, захотите signal(7) страница справочника также. –  Ignacio Vazquez-Abrams 06.11.2013, 20:01
  • 3
    ; Вы знаете, имею ли я, включают файлы в C с теми константами случайно? +1 –  Rui F Ribeiro 24.01.2018, 18:07
  • 4
    @CoryKlein, Почему Вы имеете не, выбирает это как корректный ответ? –  Rui F Ribeiro 24.01.2018, 18:08

Кажется, уместно упомянуть, что SVr4 представил waitid () в 1989 году, но пока что ни одна важная программа не использует его.waitid () позволяет получить полные 32 бита из кода exit ().

Около двух месяцев назад я переписал часть управления ожиданием / заданием Bourne Shell, чтобы использовать waitid () вместо waitpid (). Это было сделано для того, чтобы снять ограничение, маскирующее код выхода с 0xFF.

Интерфейс waitid () намного чище, чем предыдущие реализации wait (), за исключением cwait ().звонок из UNOS с 1980 года.

Возможно, вам будет интересно прочитать страницу руководства по адресу:

http://schillix.sourceforge.net/man/man1/bosh.1.html

и проверить раздел " Подстановка параметров », которая сейчас начинается на странице 8.

Новые переменные .sh. * Были введены для интерфейса waitid (). Этот интерфейс больше не имеет двусмысленного значения для известных чисел за $? и сделать взаимодействие намного проще.

Обратите внимание, что вам необходимо иметь POSIX-совместимый waitid (), чтобы иметь возможность использовать эту функцию, поэтому Mac OS X и Linux в настоящее время не предлагают этого, но waitid () эмулируется при вызове waitpid (), поэтому на платформе, отличной от POSIX, вы все равно получите только 8 бит из кода выхода.

Вкратце: .sh.status - это числовой код выхода, .sh.code - числовая причина выхода.

Для лучшей переносимости существует: .sh.codename для текстовой версии причины выхода, например. "DUMPED" и .sh.termsig, единственное имя сигнала, завершившего процесс.

Для лучшего использования существуют два значения .sh.codename, не связанных с выходом: «NOEXEC» и «NOTFOUND», которые используются, когда программа вообще не может быть запущена.

FreeBSD исправила ошибку ядра waitid () в течение 20 часов после моего отчета, Linux еще не начал с их исправлением. Я надеюсь, что через 26 лет после введения этой функции, которая есть сейчас в POSIX, все ОС вскоре будут ее поддерживать.

3
27.01.2020, 19:32

Теги

Похожие вопросы