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

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

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

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

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: Расширенное Руководство По Сценариям Bash

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

1: Catchall для общих ошибок
2: неправильное использование встроенных оболочек (согласно документации Bash)
126: вызываемая команда не может выполнить
127: "команда не найдена"
128: недопустимый аргумент для выхода
128+n: сигнал фатальной ошибки "n"
255: статус выхода из диапазона (выход принимает только целочисленные args в диапазоне 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' > > > скрипт завершается Управление-C

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

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


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

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

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

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

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

Примечания

  1. несколько ответов определяют статус выхода 2 как "неправильное использование bash builtins". Это относится только тогда, когда Баш (или сценарий 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), но были намеренно несовместимы с ней. Очень жаль.


нет стандартных кодов выхода, кроме 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, несмотря на сбой.

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

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

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

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


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

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

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


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

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

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


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

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