Существуют ли в Linux стандартные коды статуса выхода?

Процесс считается законченным в Linux, если его статус выхода равен 0.

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

Существуют ли стандартные коды выхода для процессов в Linux?

Ответ 1

8 бит кода возврата и 8 бит числа убивающего сигнала смешиваются в одно значение при возврате из wait(2) и co..

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

int main() {
    int status;

    pid_t child = fork();
    if (child <= 0)
        exit(42);
    waitpid(child, &status, 0);
    if (WIFEXITED(status))
        printf("first child exited with %u\n", WEXITSTATUS(status));
    /* prints: "first child exited with 42" */

    child = fork();
    if (child <= 0)
        kill(getpid(), SIGSEGV);
    waitpid(child, &status, 0);
    if (WIFSIGNALED(status))
        printf("second child died with %u\n", WTERMSIG(status));
    /* prints: "second child died with 11" */
}

Как вы определяете статус выхода? Традиционно оболочка хранит только 8-битный код возврата, но устанавливает высокий бит, если процесс был аномально завершен.

$ sh -c 'exit 42'; echo $?
42
$ sh -c 'kill -SEGV $$'; echo $?
Segmentation fault
139
$ expr 139 - 128
11

Если вы видите что-то другое, кроме этого, программа, вероятно, имеет обработчик сигнала SIGSEGV, который затем обычно вызывает exit, поэтому он фактически не убивается сигналом. (Программы могут выбирать любые сигналы, кроме SIGKILL и SIGSTOP.)

Ответ 2

Часть 1: Расширенный Bash Руководство по разработке сценариев

Как всегда, Advanced Bash Scripting Guide имеет отличную информацию:  (Это было связано в другом ответе, но с неканоническим URL-адресом.)

1: Catchall для общих ошибок
2: Неправильное использование встроенных оболочек (согласно документации Bash)
126: Вызываемая команда не может выполнить команду 127: "команда не найдена"
128: Недопустимый аргумент для выхода
128 + n: Сигнал фатальной ошибки "n"
255: Выход из состояния вне диапазона (выход принимает только целые аргументы в диапазоне 0 - 255)

Часть 2: sysexits.h

АБСГ ссылается на sysexits.h.

В Linux:

$ find /usr -name sysexits.h
/usr/include/sysexits.h
$ cat /usr/include/sysexits.h

/*
 * Copyright (c) 1987, 1993
 *  The Regents of the University of California.  All rights reserved.

 (A whole bunch of text left out.)

#define EX_OK           0       /* successful termination */
#define EX__BASE        64      /* base value for error messages */
#define EX_USAGE        64      /* command line usage error */
#define EX_DATAERR      65      /* data format error */
#define EX_NOINPUT      66      /* cannot open input */    
#define EX_NOUSER       67      /* addressee unknown */    
#define EX_NOHOST       68      /* host name unknown */
#define EX_UNAVAILABLE  69      /* service unavailable */
#define EX_SOFTWARE     70      /* internal software error */
#define EX_OSERR        71      /* system error (e.g., can't fork) */
#define EX_OSFILE       72      /* critical OS file missing */
#define EX_CANTCREAT    73      /* can't create (user) output file */
#define EX_IOERR        74      /* input/output error */
#define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */
#define EX_PROTOCOL     76      /* remote error in protocol */
#define EX_NOPERM       77      /* permission denied */
#define EX_CONFIG       78      /* configuration error */

#define EX__MAX 78      /* maximum listed value */

Ответ 3

'1' >>> Catchall для общих ошибок

'2' >>> Неправильное использование встроенных оболочек (согласно документации Bash)

'126' >>> Вызываемая команда не может выполнить

'127' >>> "команда не найдена"

'128' >>> Недопустимый аргумент для выхода

'128 + n' >>> Сигнал фатальной ошибки "n"

'130' >>> Сценарий, завершаемый Control-C

'255' >>> Выход из вне диапазона

Это для bash. Однако для других приложений существуют разные коды выхода.

Ответ 4

Ни один из более старых ответов не описывает состояние выхода 2 правильно. Вопреки тому, что они утверждают, статус 2 - это то, что действительно возвращает утилиты командной строки при неправильном вызове. (Да, ответ может быть девятилетним, иметь сотни upvotes, и все равно быть неправ.)

Вот реальное, давнее соглашение о статусе выхода для нормального завершения, т.е. Не по сигналу:

  • Статус выхода 0: успех
  • Состояние выхода 1: "сбой", как определено программой
  • Статус выхода 2: ошибка использования командной строки

Например, diff возвращает 0, если файлы, которые он сравнивает, идентичны, и 1, если они отличаются. По давнему соглашению, программы unix возвращают статус выхода 2 при неправильном вызове (неизвестные параметры, неправильное количество аргументов и т.д.) Например, diff -N, grep -Y или diff abc приведут к $? устанавливается на 2. Это и было практикой с первых дней Unix в 1970-х годах.

В принятом ответе объясняется, что происходит, когда команда завершается сигналом. 128+[<signal number> говоря, прекращение из-за непроверенного сигнала приводит к статусу выхода 128+[<signal number>. Например, завершение с помощью SIGINT (сигнал 2) приводит к состоянию выхода 130.

Заметки

  1. Несколько ответов определяют статус выхода 2 как "Неправильное использование встроенных настроек bash". Это применимо только тогда, когда bash (или сценарий bash) выходит со статусом 2. Рассмотрим его как частный случай неправильной ошибки использования.

  2. В sysexits.h, упомянутом в наиболее популярном ответе, статус выхода EX_USAGE ("ошибка использования командной строки") определяется как 64. Но это не отражает реальности: мне неизвестно какую-либо общую утилиту Unix, которая возвращает 64 неверных вызов (примеры приветствуются). Тщательное чтение исходного кода показывает, что sysexits.h является желательным, а не отражением истинного использования:

     *    This include file attempts to categorize possible error
     *    exit statuses for system programs, notably delivermail
     *    and the Berkeley network.
    
     *    Error numbers begin at EX__BASE [64] to reduce the possibility of 
     *    clashing with oth­er exit statuses that random programs may 
     *    already return. 
    

    Другими словами, эти определения не отражают общей практики в то время (1993), но были намеренно несовместимы с ней. Больше жаль.

Ответ 5

Нет стандартных кодов выхода, кроме 0 означает успех. Без нуля не обязательно означает отказ.

stdlib.h определяет EXIT_FAILURE как 1 и EXIT_SUCCESS как 0, но об этом.

11 на segfault интересен, поскольку 11 - это номер сигнала, который ядро ​​использует для уничтожения процесса в случае segfault. Вероятно, есть какой-то механизм, либо в ядре, либо в оболочке, который преобразует это в код выхода.

Ответ 6

sysexits.h имеет список стандартных кодов выхода. Похоже, что он насчитывает не менее 1993 года, и некоторые крупные проекты, такие как Postfix, используют его, поэтому я представляю себе, как это сделать.

На странице руководства OpenBSD:

Согласно стилю (9), неплохо было бы назвать exit (3) с arbi- trary, чтобы указать условие отказа при завершении программы. В- вместо этого следует использовать предопределенные коды выхода из сисикситов, поэтому вызывающий процесс может получить приблизительную оценку класса отказа без поиска исходного кода.

Ответ 7

В первом приближении 0 является sucess, отличным от нуля, является отказ, при этом 1 является общим отказом, а что-то большее, чем одно, является конкретным сбоем. Помимо тривиальных исключений из ложных и тестов, которые оба предназначены для получения 1 для успеха, есть еще несколько исключений, которые я нашел.

Более реалистично, 0 означает sucess или, возможно, сбой, 1 означает общий сбой или, может быть, sucess, 2 означает общий сбой, если 1 и 0 оба используются для успеха, но, возможно, также подходят.

Команда diff дает 0, если сопоставленные файлы идентичны, 1, если они отличаются, и 2, если бинарные файлы разные. 2 также означает отказ. Команда less дает 1 для отказа, если вы не предоставите аргумент, и в этом случае он выйдет из 0, несмотря на неудачу.

Чем больше команда и команда заклинания дают 1 для отказа, если отказ не является результатом отказа в разрешении, несуществующего файла или попытки прочитать каталог. В любом из этих случаев они выходят из 0, несмотря на неудачу.

Затем команда expr дает 1 для sucess, если вывод не является пустой строкой или нулем, и в этом случае 0 является sucess. 2 и 3 - неисправность.

Тогда есть случаи, когда успех или неудача неоднозначны. Когда grep не находит шаблон, он выходит из 1, но он выходит из 2 для подлинного сбоя (например, разрешения отклонено). Klist также выходит из 1, когда ему не удается найти билет, хотя на самом деле это не больше, чем когда grep не находит шаблон или когда вы используете пустой каталог.

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

Ответ 8

Программы возвращают 16-битный код выхода. Если программа была убита сигналом, то старший байт содержит используемый сигнал, в противном случае младший байт - это статус выхода, возвращаемый программистом.

Как этот код завершения присваивается переменной состояния $? тогда до оболочки. Bash сохраняет более низкие 7 бит состояния, а затем использует 128 + (сигнал nr) для указания сигнала.

Единственное "стандартное" соглашение для программ - 0 для успеха, отличное от нуля для ошибки. Другое соглашение - вернуть errno при ошибке.

Ответ 9

Стандартные коды выхода Unix определяются sysexits.h, как упоминается еще один плакат. Те же коды выхода используются портативными библиотеками, такими как Poco, - вот список из них:

http://pocoproject.org/docs/Poco.Util.Application.html#16218

Сигнал 11 представляет собой сигнал SIGSEGV (нарушение сегмента), который отличается от кода возврата. Этот сигнал генерируется ядром в ответ на плохой доступ к странице, что приводит к завершению работы программы. Список сигналов можно найти на странице управления сигналом (запустить "человеческий сигнал" ).

Ответ 10

Когда Linux возвращает 0, это означает успех. Все остальное означает отказ, каждая программа имеет свои собственные коды выхода, поэтому было бы довольно сложно перечислить их все...!

О коде ошибки 11, это действительно номер ошибки сегментации, в основном означающий, что программа обратилась к ячейке памяти, которая не была назначена.