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


процесс считается правильно завершенным в Linux, если его состояние выхода равно 0.

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

есть ли стандартные коды выхода для процессов в Linux?

10 272

10 ответов:

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.)

Часть 1: Advanced Bash Scripting Guide

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

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

Часть 2: sysexits.h

ссылки на ABSG 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 */

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

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

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

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

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

'128+n'>> > сигнал неустранимой ошибки "n"

'130'>>> скрипт завершен Control-C

'255'>>>состояние выхода из диапазона

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

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

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

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

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

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

Примечания

  1. несколько ответов определяют статус выхода 2 как "неправильное использование встроенных 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. 
    

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

stdlib.ч не определяют EXIT_FAILURE 1 и EXIT_SUCCESS Как 0,но это все.

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

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

с man-страницы OpenBSD:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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