Резюме
Каждая команда Linux сообщает об ошибках в случае неудач, однако полагаться на такие сообщения бывает непросто. Ваши скрипты должны использовать коды завершения для повышения надежности.
Что такое коды завершения?
Когда вы выполняете команду в Linux, она может завершиться с ошибкой. Причин для этого множество, но обычно вы получите сообщение, поясняющее ситуацию:
Сообщение об ошибке выводится в STDERR, который отделен от STDOUT, что позволяет различать ошибки и ожидаемый вывод. Для пользователя описание ошибки должно быть информативным, но скрипты и другие автоматизированные процессы требуют более надежного метода обработки ошибок.
Что такое stdin, stdout и stderr в Linux?
Не понимаете, что такое stdin, stdout и stderr? Узнайте, как использовать их в своих скриптах Linux.
Каждая команда также выводит код завершения. Это число от 0 до 255, указывающее, завершилась ли команда успешно или с ошибкой. По умолчанию код завершения остается скрытым, но ваша оболочка предоставляет доступ к этому значению через специальную переменную $?
Обратите внимание, что значение 0 указывает на успех, а ненулевое значение — на ошибку. Вы можете проверить это значение в командной строке, использовать его в скрипте и контролировать выполнение своих программ.
Как использовать коды завершения?
В приведенном выше примере команда ls вернула код завершения 0 при успешном выполнении и 1, если ее аргументом был неверный файл. Это может показаться странным, так как многие языки программирования интерпретируют 0 как ложное значение, а 1 как истинное. Однако такая схема позволяет иметь одно универсальное значение успеха и широкий диапазон значений для различных типов ошибок.
Кроме того, помимо вывода значения переменной $?, вы можете использовать его в условном операторе if. Если команда возвращает код завершения 0, условие выполнит соответствующий блок then. В противном случае, если он существует, выполнится блок else. Например:
Вы можете использовать эту конструкцию в скрипте оболочки, где будет легче форматировать для удобочитаемости:
Это эквивалентно:
Длинная версия использует синтаксис с квадратными скобками для проверки значения $?, но зачастую проще проверить значение напрямую, как в первом случае. Помните, что $? всегда представляет код завершения последней выполненной команды, поэтому будьте осторожны. У вас может возникнуть желание вывести значение $? для отладки, например:
Но на момент проверки условия $? будет содержать значение кода завершения echo, которое практически всегда будет равно 0. Чтобы избежать этого, либо тестируйте команду напрямую в условии, либо сохраните значение $? в переменной.
Как использовать условные операторы if в Bash (с 4 примерами)
Условный оператор if — это самый простой способ познакомиться с условным выполнением в скриптах Bash.
Что ещё следует знать о кодах завершения?
Коды завершения довольно просты, следуя принципам Unix, и это часть их силы. Но есть некоторые подводные камни и исключения, о которых стоит знать.
Коды завершения в вашей оболочке
Ваша оболочка использует коды завершения даже в тех случаях, когда введенная вами команда не исполнилась корректно. Например, zsh и bash возвращают 127, если команда не найдена, и 126, если команду нельзя выполнить:
Необычные коды завершения
Некоторые команды немного отклоняются от правил кодов завершения; это, в сущности, просто соглашения. Например, команда diff использует значение 0 для обозначения «нет различий», 1 для обозначения «различия» и 2 для обозначения ошибки:
Это может запутать, особенно в условных операторах; например:
Команда curl также ведет себя немного непредсказуемо. Вы можете ожидать, что curl будет сообщать о HTTP-ошибке, такой как 404 для несуществующего URL, как ненулевой статус код, но это не так:
Вы можете использовать опцию -f (--fail), чтобы заставить curl вести себя иначе, возвращая код завершения 22 при ошибке:
Однако учтите, что это не 100% гарантировано, и некоторые HTTP-ошибки, включая те, которые требуют аутентификации, все равно вернут код завершения 0.
Использование кодов завершения в цепочке команд
Одно из лучших применений кодов завершения происходит без необходимости задумываться об этом. Вот простой пример:
Операторы логического И && и ИЛИ || позволяют вам запускать более одной команды в зависимости от кода завершения предыдущих. Они аналогичны соответствующим операторам в большинстве языков программирования, но следуют условной конвенции кодов завершения. Оператор && выполнит команду справа, только если команда слева возвращает код завершения 0. Оператор || выполнит команду справа, только если команда слева завершится с ненулевым статусом.
Очень распространенный случай возникает, когда вы собираете программное обеспечение с нуля, используя следующий рецепт:
Три части этой команды выполняют следующие действия:
Если любая часть этого процесса завершится неудачно, он немедленно остановится, не пытаясь выполнить оставшуюся часть.
Команды true и false
В вашей системе Linux есть две интересные команды: true и false. Каждая из них выполняет лишь одну функцию: возвращает соответствующий код завершения — 0 и 1 соответственно:
Они могут показаться не очень полезными, но эти команды полезны для тестирования и некоторых задач в скриптах оболочки. Вы можете использовать true в операторе while для создания бесконечного цикла:
Вы также можете использовать их вместе с логическими операторами для изменения поведения команд. Например, вы можете временно остановить выполнение длинной цепочки команд:
Или вы можете заставить цепочку команд продолжать выполнение, даже если одна из команд завершилась с ошибкой:
Возврат кода завершения из собственных скриптов
Вы, вероятно, уже использовали команду exit, чтобы выйти из вашего терминала. Технически, она завершает вашу оболочку, и это означает, что вы можете использовать ее для завершения и скрипта оболочки. По умолчанию ваши скрипты завершатся с тем же кодом, что и последняя выполненная команда:
Но вы можете изменить код завершения, передав числовой параметр команде exit:
Теперь ваш скрипт завершится с тем статусом, который вы указали, и вы сможете использовать это для передачи различных условий ошибок от вашей программы к другим.
Как только вы освоитесь с ними, команды завершения будут легко использовать. Вы даже можете применять их, не задумываясь об этом, но при работе со скриптами убедитесь, что используете коды завершения правильно.
Если вам понравилась эта статья, подпишитесь, чтобы не пропустить еще много полезных статей!
Вы также можете найти наши материалы в:
- Telegram: https://t.me/gergenshin
- Youtube: https://www.youtube.com/@gergenshin
- Яндекс Дзен: https://dzen.ru/gergen
- Официальный сайт: https://www-genshin.ru