Как получить список кодов выхода (и / или кодов возврата) и значения для команды / утилиты?

17

Есть ли способ сделать то, что указано в заголовке из терминальных команд, или мне придется посмотреть на коды?

точный
источник

Ответы:

15

Не существует «рецепта» для получения значений статуса выхода данной терминальной команды.

Моей первой попыткой была бы справочная страница:

user@host:~# man ls 
   Exit status:
       0      if OK,

       1      if minor problems (e.g., cannot access subdirectory),

       2      if serious trouble (e.g., cannot access command-line argument).

Второе : гугл . Смотрите wget в качестве примера.

Третье : статусы выхода оболочки, например bash. Bash и его встроенные команды могут использовать значения выше 125 специально. 127 для команды не найдена, 126 для команды не выполнима. Для получения дополнительной информации см. Коды выхода bash .

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

Коды выхода указывают на состояние сбоя при завершении программы, и они находятся в диапазоне от 0 до 255. Оболочка и ее встроенные функции могут использовать, в частности, значения выше 125 для обозначения конкретных режимов сбоя, поэтому список кодов может различаться в зависимости от оболочек и операционных систем (например, Bash). использует значение 128 + N в качестве состояния выхода). См .: Bash - 3.7.5 Статус выхода или man bash.

Обычно нулевое состояние выхода указывает на то, что команда выполнена успешно , ненулевое состояние выхода указывает на ошибку .

Чтобы проверить, какой код ошибки возвращается командой, вы можете напечатать $?последний код выхода или ${PIPESTATUS[@]}который выдает список значений состояния выхода из конвейера (в Bash) после выхода из сценария оболочки.

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

Некоторый список сисекситов в Linux и BSD / OS X с предпочтительными кодами выхода для программ (64-78) можно найти в /usr/include/sysexits.h(или: man sysexitsв BSD):

0   /* successful termination */
64  /* base value for error messages */
64  /* command line usage error */
65  /* data format error */
66  /* cannot open input */
67  /* addressee unknown */
68  /* host name unknown */
69  /* service unavailable */
70  /* internal software error */
71  /* system error (e.g., can't fork) */
72  /* critical OS file missing */
73  /* can't create (user) output file */
74  /* input/output error */
75  /* temp failure; user is invited to retry */
76  /* remote error in protocol */
77  /* permission denied */
78  /* configuration error */
/* maximum listed value */

Приведенный выше список выделяет ранее неиспользованные коды выхода из 64-78. Диапазон нераспределенных кодов выхода будет в дальнейшем ограничен.

Однако приведенные выше значения в основном используются в sendmail и используются практически никем другим, поэтому они не являются чем-то отдаленно близким к стандарту (как указано @Gilles ).

В оболочке статус выхода следующий (на основе Bash):

  • 1- 125- Команда не выполнена успешно. Проверьте man-страницу команды на предмет значения статуса, несколько примеров ниже:

  • 1 - Catchall для общих ошибок

    Разные ошибки, такие как «деление на ноль» и другие недопустимые операции.

    Пример:

    $ let "var1 = 1/0"; echo $?
    -bash: let: var1 = 1/0: division by 0 (error token is "0")
    1
    
  • 2 - Неправильное использование встроенных командных оболочек (согласно документации Bash)

    Отсутствует ключевое слово или команда, или проблема с правами доступа (и код возврата diff при неудачном сравнении двоичных файлов).

    Пример:

     empty_function() {}
    
  • 6 - Нет такого устройства или адреса

    Пример:

    $ curl foo; echo $?
    curl: (6) Could not resolve host: foo
    6
    
  • 124 - время ожидания команды

  • 125- если команда не работает, см .: coreutils
  • 126 - если команда найдена, но не может быть вызвана (например, не является исполняемой)

    Проблема с разрешением или команда не являются исполняемыми.

    Пример:

    $ /dev/null
    $ /etc/hosts; echo $?
    -bash: /etc/hosts: Permission denied
    126
    
  • 127 - если команда не может быть найдена, дочерний процесс, созданный для ее выполнения, возвращает этот статус

    Возможна проблема с $PATHопечаткой.

    Пример:

    $ foo; echo $?
    -bash: foo: command not found
    127
    
  • 128 - Неверный аргумент exit

    Выход принимает только целочисленные аргументы в диапазоне 0 - 255.

    Пример:

    $ exit 3.14159
    -bash: exit: 3.14159: numeric argument required
    
  • 128- 254- сигнал фатальной ошибки "n" - команда умерла из-за получения сигнала. Код сигнала добавляется к 128 (128 + SIGNAL), чтобы получить статус (Linux:, man 7 signalBSD:) man signal, несколько примеров ниже:

  • 130 - команда прекращена из-за нажатия Ctrl-C, 130-128 = 2 (SIGINT)

    Пример:

    $ cat
    ^C
    $ echo $?
    130
    
  • 137- если команде отправляется KILL(9)сигнал (128 + 9), в противном случае статус выхода команды

    kill -9 $PPID сценария.

  • 141- SIGPIPE- запись на трубе, без считывателя

    Пример:

    $ hexdump -n100000 /dev/urandom | tee &>/dev/null >(cat > file1.txt) >(cat > file2.txt) >(cat > file3.txt) >(cat > file4.txt) >(cat > file5.txt)
    $ find . -name '*.txt' -print0 | xargs -r0 cat | tee &>/dev/null >(head /dev/stdin > head.out) >(tail /dev/stdin > tail.out)
    xargs: cat: terminated by signal 13
    $ echo ${PIPESTATUS[@]}
    0 125 141
    
  • 143 - команда прекращается сигнальным кодом 15 (128 + 15 = 143)

    Пример:

    $ sleep 5 && killall sleep &
    [1] 19891
    $ sleep 100; echo $?
    Terminated: 15
    143
    
  • 255* - выход из состояния вне диапазона.

    Выход принимает только целочисленные аргументы в диапазоне 0 - 255.

    Пример:

    $ sh -c 'exit 3.14159'; echo $?
    sh: line 0: exit: 3.14159: numeric argument required
    255
    

В соответствии с приведенной выше таблицей коды выхода 1 - 2, 126 - 165 и 255 имеют специальные значения, поэтому их следует избегать для параметров выхода, указанных пользователем.

Обратите внимание, что значения выхода из диапазона могут привести к неожиданным кодам выхода (например, выход 3809 дает код выхода 225, 3809% 256 = 225).

Видеть:

kenorb
источник
errnoзначения используются системными API, они не используются в качестве состояний выхода (они даже не находятся в нужном диапазоне), и они не имеют отношения к сценариям оболочки. Значения Sysexits взяты из sendmail и используются практически никем, они не являются чем-то отдаленно близким к стандарту.
Жиль "ТАК ... перестать быть злым"
7

Вам придется заглянуть в код / ​​документацию. Однако вещь, которая ближе всего подходит к «стандартизации», это errno.h

Торстен Стэрк
источник
спасибо за указание файла заголовка .. попробовал заглянуть в документацию нескольких утилит .. трудно найти коды выхода, кажется, большинство из них будут stderrs ...
точные
3
errno.hне имеет значения, когда дело доходит до кодов выхода, только сообщения об ошибках.
Жиль "ТАК - перестань быть злым"
Большинство программ возвращают коды выхода в соответствии с соглашением BSD, как изложено в sysexits.h. Тем не менее, некоторые программы возвращают errnos, и я думаю, что возвращение errnos имеет смысл. Необработанные errnos распространяются вверх, как исключения, ( errnoпребывания, функции возвращают, например, -1или 0|NULL). Поскольку программы - это просто функции, хотя и функции, которые выполняются в отдельном адресном пространстве, имеет смысл, что программа может продолжить errnoраспространение через границу процесса.
PSkocik
@PSkocik, у вас есть пример такой команды? errnos не являются переносимыми (значения не согласованы в разных системах), и нет переносимого способа получить имя или сообщение об ошибке из значения (в zsh есть встроенная функция для этого). Не говоря уже о том, что некоторые системы имеют ошибки выше 123, которые могут конфликтовать с общими кодами ошибок специального значения . Обычно команды печатают сообщения из errno и возвращают статус успешного завершения / сбоя. Команды предназначены для пользователей. Функции / системные вызовы предназначены для программистов.
Стефан Шазелас
@ StéphaneChazelas Я видел это пару раз, но не в каких-либо хорошо известных программах, я должен признать. Я лично возвращал errno + 1 в своей игрушечной системе в последнее время (так что 1 продолжает означать «любая ошибка»), потому что я думаю, что сериализация errno через границу процесса имеет больший смысл, чем перевод в соответствии с соглашением BSD, так как выполнение программы по существу, вызовы функций, а функции используют errno. Я использую свой собственный декодер состояния последнего выхода в моем PROMPT_COMMAND (bash), поэтому я получаю что-то вроде "($numeric_code|$bsd_decoded|$errno_plus_one_decoded)".
PSkocik
1

Насколько я знаю, есть только два, более или менее, стандартных значения - оба определены stdlib.hдля использования с exit ():

  • EXIT_SUCCESS (= 0)
  • EXIT_FAILURE (= 1)

И единственное стандартное значение де-факто, то есть имеющее одинаковое значение для всех программ в мире, это 0 (ноль), что означает УСПЕХ.

Различные программы вводят разные списки возвращаемых кодов «сбоя», чтобы различать или подчеркивать разные ошибки (разные типы или серьезность). Некоторые программы даже используют возвращенное значение, чтобы сообщить целое число обнаруженных ошибок времени выполнения (например, количество неудачных юнит-тестов в костюме).

Я бы не рекомендовал вводить какой-либо «новый стандарт», расширяющий stdlib.h

xoiss
источник