как посмотреть код возврата
Bash получить код завершения команды в Linux / Unix
Я новый пользователь системы Linux. Как мне получить код завершения команды?
Как получить код вывода или статус команды оболочки Linux или Unix и сохранить его в переменной оболочки?
Введение. Каждая команда оболочки Linux или Unix возвращает состояние, когда она завершается нормально или ненормально.
Например, если скрипт backup.sh не выполнен, и он возвращает код, который сообщает скрипту оболочки отправить электронное письмо админу.
Что такое код вывода в оболочке bash?
Каждая команда Linux или Unix, выполняемая скриптом оболочки или пользователем, имеет статус вывода.
Статус вывода – это целое число.
0 состояние выхода означает, что команда была успешной без каких-либо ошибок.
Ненулевое (1-255 значений) состояние выхода означает, что команда была неудачной.
Как узнать код вывода команды
Из приведенных выше выводов ясно, что код вывода 0 означает, что команда date была успешной.
Кроме того, код вывода – 127 (не ноль), так как команда nonexistant не была успешной.
Bash как получить код завершения команды – Как использовать коды вывода в скриптах оболочки
Итак, как вы сохранить статус вывода команды в переменной оболочки?
Как мне установить код вывода для моих собственных скриптов оболочки?
Команда exit вызывает обычное завершение скриптов оболочки.
Вывод из оболочки со статусом N. Синтаксис:
Пример скрипта оболочки для получения кода завершения команды
Заключение
На этой странице показано, как использовать коды вывода в системах на основе Linux или Unix и как получить статус вывода / код команды.
Как получить список кодов выхода (и / или кодов возврата) и значения для команды / утилиты?
Есть ли способ сделать то, что указано в заголовке из терминальных команд, или мне придется посмотреть на коды?
Не существует «рецепта» для получения значений статуса выхода данной терминальной команды.
Моей первой попыткой была бы справочная страница:
Нет полного списка всех кодов выхода, которые могут быть найдены, однако была предпринята попытка систематизировать номера статуса выхода в исходном коде ядра, но это в основном предназначено для программистов на C / C ++, и подобный стандарт для сценариев может быть уместным.
Некоторый список сисекситов в Linux и BSD / OS X с предпочтительными кодами выхода для программ (64-78) можно найти в /usr/include/sysexits.h (или: man sysexits в BSD):
Приведенный выше список выделяет ранее неиспользованные коды выхода из 64-78. Диапазон нераспределенных кодов выхода будет в дальнейшем ограничен.
Однако приведенные выше значения в основном используются в sendmail и используются практически никем другим, поэтому они не являются чем-то отдаленно близким к стандарту (как указано @Gilles ).
В оболочке статус выхода следующий (на основе Bash):
Разные ошибки, такие как «деление на ноль» и другие недопустимые операции.
Отсутствует ключевое слово или команда, или проблема с правами доступа (и код возврата diff при неудачном сравнении двоичных файлов).
Проблема с разрешением или команда не являются исполняемыми.
Обратите внимание, что значения выхода из диапазона могут привести к неожиданным кодам выхода (например, выход 3809 дает код выхода 225, 3809% 256 = 225).
Вам придется заглянуть в код / документацию. Однако вещь, которая ближе всего подходит к «стандартизации», это errno.h
И единственное стандартное значение де-факто, то есть имеющее одинаковое значение для всех программ в мире, это 0 (ноль), что означает УСПЕХ.
Различные программы вводят разные списки возвращаемых кодов «сбоя», чтобы различать или подчеркивать разные ошибки (разные типы или серьезность). Некоторые программы даже используют возвращенное значение, чтобы сообщить целое число обнаруженных ошибок времени выполнения (например, количество неудачных юнит-тестов в костюме).
Как использовать коды завершения в Bash-скриптах
Инструменты автоматизации и мониторинга удобны тем, что разработчик может взять готовые скрипты, при необходимости адаптировать и использовать в своём проекте. Можно заметить, что в некоторых скриптах используются коды завершения (exit codes), а в других нет. О коде завершения легко забыть, но это очень полезный инструмент. Особенно важно использовать его в скриптах командной строки.
Что такое коды завершения
В Linux и других Unix-подобных операционных системах программы во время завершения могут передавать значение родительскому процессу. Это значение называется кодом завершения или состоянием завершения. В POSIX по соглашению действует стандарт: программа передаёт 0 при успешном исполнении и 1 или большее число при неудачном исполнении.
Почему это важно? Если смотреть на коды завершения в контексте скриптов для командной строки, ответ очевиден. Любой полезный Bash-скрипт неизбежно будет использоваться в других скриптах или его обернут в однострочник Bash. Это особенно актуально при использовании инструментов автоматизации типа SaltStack или инструментов мониторинга типа Nagios. Эти программы исполняют скрипт и проверяют статус завершения, чтобы определить, было ли исполнение успешным.
Кроме того, даже если вы не определяете коды завершения, они всё равно есть в ваших скриптах. Но без корректного определения кодов выхода можно столкнуться с проблемами: ложными сообщениями об успешном исполнении, которые могут повлиять на работу скрипта.
Что происходит, когда коды завершения не определены
В Linux любой код, запущенный в командной строке, имеет код завершения. Если код завершения не определён, Bash-скрипты используют код выхода последней запущенной команды. Чтобы лучше понять суть, обратите внимание на пример.
Как использовать коды завершения в Bash-скриптах
Проверяем коды завершения
После рефакторинга скрипта получаем такое поведение:
Создаём собственный код завершения
Как использовать коды завершения в командной строке
Скрипт уже умеет сообщать пользователям и программам об успешном или неуспешном выполнении. Теперь его можно использовать с другими инструментами администрирования или однострочниками командной строки.
Скрипт использует коды завершения, чтобы понять, была ли команда успешно выполнена. Если коды завершения используются некорректно, пользователь скрипта может получить неожиданные результаты при неудачном выполнении команды.
Дополнительные коды завершения
Адаптированный перевод статьи Understanding Exit Codes and how to use them in bash scripts by Benjamin Cane. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.
Bash: как поймать код возврата фонового процесса?
А можно ли в Bash узнать код возврата фонового процесса?
Как сие можно провернуть?
Если запускаемый процесс зависнет по ин/оуту (а в моем случае он может) то wait тоже зависнет. То есть, нужно либо получить код возврата, либо прибить процесс по истечении некоторого времени.
Прибить процесс не проблема, ибо известен ПИД. А как поймать код возврата в вышеозначенных условиях?
wait может сообщить статус уже убитого процесса:
Но это всё не нужно, поскольку есть утилита timeout:
нужно либо получить код возврата, либо прибить процесс по истечении некоторого времени.
.
Если команда завершилась по таймауту, то код завершения 124. Иначе
возвращается полученный код завершения КОМАНДЫ. Если сигнал не задан
то по таймауту посылается сигнал TERM.
возвращается полученный код завершения КОМАНДЫ
Вот тут поточнее. Что будет возвращено в случае выполнения строки команд, разделенных символом «;»? Что будет в случае команды вызова скрипта?
Что будет возвращено в случае выполнения строки команд, разделенных символом «;»?
Проблема все еще не решена.
Wait не работает так как описано. Пример:
С утилитой timeout вообще непонятки. Ее по каким-то причинам нет в CentOs 5.8. Так что воспользоваться ей не могу.
Wait не работает так как описано.
Наверное, я плохо пояснил: wait возвращает exit code процесса в своём exit code:
С утилитой timeout вообще непонятки. Ее по каким-то причинам нет в CentOs 5.8. Так что воспользоваться ей не могу.
timeout появился в coreutils в районе версии 7.3. Есть ещё утилита timelimit с похожим функционалом.
Возможно, апплет timeout есть в busybox:
Если запускаемый процесс зависнет по ин/оуту (а в моем случае он может) то wait тоже зависнет.
Как вариант можно по истечении необходимого интервала времени выполнить
Коды возврата & исключения
Замечательные статьи публиковались в последнее время, хотелось бы добавить ещё несколько абзацев по данной теме.
Уважаемые авторы предыдущих топиков как-то упускали тот момент (или мне показалось? или это само-собой подразумевается?) что exceptions возникли как инструмент для решения весьма утилитарной задачи — передачи управления из места возникновения ошибки в то место, где она может быть обработана.
Немного истории, чтобы понятно было, откуда такая задача возникла. В каждом более-менее нетривиальном программном обеспечении (сложнее, чем «Hello, world», да) всегда существуют точки, где нормальное выполнение не может продолжаться — I/O подсистема выдала отказ, памяти для алгоритма почему-то не хватило, входные параметры для функции ей не понравились и т.п. Как именно реагировать?
Ситуация становится ещё печальней, если рассматривать создание какой-либо библиотеки, которая должна будет использоваться в других проектах. Мы не можем (как следствие) вызывать assert/abort или ещё какую-нибудь подобный обработчик — откуда мы знаем, что имеем право завершать работу всего приложения? К примеру, наша библиотека занимается сбором какой-то статистики входных данных, а из-за такого её поведения будет остановлена работа всего устройства. А пишем мы firmware для кардиостимулятора, конечно же.
Ок, abort() — не годится. Мы не хотим создавать приложения, подобные воздушному шарику — в любом месте уколол, весь шарик умер. Мы хотим пользоваться технологией, которая позволит разделить место, где возникла ошибка, и место где принимается решение о том, что именно мы будем делать с этой ошибкой. Так как для одних применений реакцией будет запрет сбора этой статистики, для других — переинициализация библиотеки (например, с другими параметрами), где-то — просто игнорирование. Так как на более высоком уровне доступно гораздо больше информации о том, как реагировать на возникшую ошибку.
Собственно, написано это всё было для того, чтобы лучшее понимание «для чего именно» служат exceptions позволяло лучше понимать «а как их применять и для каких случаях».
PS: ещё было желание показать на примерах кода, какие именно минусы есть у exceptions. И как решалась задача «и ошибки удобно обрабатывать и exceptions при этом не использовать» (актуально для встроенных систем, когда «кардиостимуляторы» пишутся). Но это позже.