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

Можно закрыть stderr как в:

ls /blah 2>&-

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

Это также означает, что любая запись к stderr, сделанному приложением, возвратилась бы с ошибкой (EBADF), который может влиять на их поведение.

Поскольку каналы позволяются, Вы могли предоставить команду, которая отбрасывает весь ее вход. Здесь, использование grep -v '^' (но Вы могли использовать tail -n 0 или sed d или названный сценарий discard это делает cat > /dev/null):

{ ls /blah 2>&1 >&3 | grep -v '^'; } 3>&1

С другой стороны, у Вас мог быть независимо от того, что, запускается, к которому ограниченная оболочка запускает его с fd 3 (например), перенаправленного /dev/null (rbash 3> /dev/null), таким образом, можно затем сделать в ограниченной оболочке:

ls /blah 2>&3

Который позволяется:

$ rbash -c 'ls /blah 2>&3' 3> /dev/null
$

Можно проверить ли перенаправление к /dev/null позволяется/работается или не с:

if true 2>&- > /dev/null; then
  echo allowed
fi

Можно проверить, ограничивается ли оболочка или не с:

case $- in
  (*r*) echo restricted
esac
17
23.01.2014, 01:41
4 ответа

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

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

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

Во-вторых: Google. См. wget как пример.

В-третьих: статусы выхода оболочки, например, колотите. Bash и это являются builtins, может использовать значения выше 125 особенно. 127 для команды, не найденной, 126 для команды не исполняемый файл. Для получения дополнительной информации см. коды выхода удара.

15
27.01.2020, 19:46
  • 1
    да некоторый человек, информация... страницы действительно включает их.. и я был обеспокоен теми, кто не сделал... и я знаю, что веб-исследование всегда является опцией... что касается теперь кажется, что это были просто коды выхода удара, которые я должен был искать.. –  precise 22.01.2014, 11:09

Необходимо будет изучить код/документацию. Однако вещью, которая прибывает самая близкая к "стандартизации", является errno.h

7
27.01.2020, 19:46
  • 1
    благодарит указать на заголовочный файл.. испытанное изучение документации нескольких utils.. трудное время находя коды выхода, кажется, больше всего будет stderrs... –  precise 22.01.2014, 11:13
  • 2
    errno.h не важно когда дело доходит до кодов выхода, только сообщений об ошибках. –  Gilles 'SO- stop being evil' 23.01.2014, 01:41
  • 3
    Большинство программ возвращает коды выхода согласно конвенции BSD, как размечено в sysexits.h. Однако некоторые программы действительно возвращаются errnos, и я на самом деле думаю, возвращаясь errnos имеет большую часть смысла. Необработанный errnos распространяют вверх, как исключения, ( errno остается, возврат функций, например, -1 или 0|NULL). Так как программы являются просто функциями, хотя функции, которые выполняются в отдельном адресном пространстве, оно имеет смысл, который программа могла бы хотеть продолжить errno распространение через границу процесса. –  PSkocik 12.01.2016, 02:14
  • 4
    @PSkocik, у Вас есть пример такой команды? errnos не являются портативными (оценивает не последовательный через системы), и нет никакого портативного способа получить допускать ошибку имя, или сообщение от значения (zsh имеет встроенное для этого). Не говоря уже о том, что некоторые системы имеют errnos выше 123, который столкнулся бы с общими кодами ошибок особого значения. Обычно, команды печатают сообщения от errno и возвращают статус выхода успеха/отказа. команды предназначаются для пользователей. функции/системные вызовы предназначаются для программистов. –  Stéphane Chazelas 07.09.2016, 11:17
  • 5
    @StéphaneChazelas, я видел его пару раз, но не в любых хорошо установленных программах, я должен признать. Я лично возвращал errno+1 в своей игрушечной системе в последнее время (так, чтобы 1 продолжил означать "любую ошибку"), потому что я думаю, сериализируя errno's через границу процесса, имеет лучший смысл, чем перевод согласно конвенции BSD, поскольку выполнение программы является чрезвычайно вызовами функции, и функции используют errno. Я использую свой собственный декодер последнего статуса выхода в моем PROMPT_COMMAND (удар), таким образом, я получаю что-то как "($numeric_code|$bsd_decoded|$errno_plus_one_decoded)". –  PSkocik 07.09.2016, 12:00

Коды выхода указывают на условия отказа при завершении программы и находятся в диапазоне от 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).

В shell статус завершения следующий (на основе Bash):

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

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

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

    Пример:

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

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

    Example:

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

    Пример:

    $ curl foo; echo $?
    curl: (6) Could not resolve host: foo
    6
    
  • 124 - команда завершилась

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

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

    Example:

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

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

    Пример:

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

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

    Пример:

    $ exit 3.14159
    -bash: exit: 3.14159: требуется числовой аргумент
    
  • 128-254 - сигнал фатальной ошибки "n" - команда умерла из-за получения сигнала. Код сигнала прибавляется к 128 (128 + SIGNAL) для получения статуса (Linux: man 7 signal, BSD: 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: завершено сигналом 13
    $ echo ${PIPESTATUS[@]}
    0 125 141
    
  • 143 - команда завершена сигналом с кодом 15 (128+15=143)

    Пример:

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

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

    Пример:

    $ sh -c 'exit 3.14159'; echo $?
    sh: строка 0: exit: 3.14159: требуется числовой аргумент
    255
    

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

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

См.:

12
27.01.2020, 19:46

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

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

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

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

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

0
20.08.2021, 12:58

Теги

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