Я хочу вызвать ошибку в сценарии Bash с сообщением «Test case Failed !!!». Как это сделать в Баше?
Например:
if [ condition ]; then
raise error "Test cases failed !!!"
fi
linux
bash
shell
error-handling
Навин Кумар
источник
источник
echo you screwed up at ... | mail -s BUG $bugtrackeremailaddress
?Ответы:
Это зависит от того, где вы хотите сохранить сообщение об ошибке.
Вы можете сделать следующее:
Или следующее:
Когда вы вызываете исключение, вы останавливаете выполнение программы.
Вы также можете использовать что-то вроде
exit xxx
гдеxxx
находится код ошибки, который вы, возможно, захотите вернуть в операционную систему (от 0 до 255). Here125
и64
просто случайные коды Вы можете выйти с. Если вам необходимо указать ОСА , что программа остановлена неправильно (например , произошла. Ошибка), вы должны передать код выхода ненулевого вexit
.Как отметил @chepner , вы можете сделать
exit 1
, что будет означать неопределенную ошибку .источник
1>&2
сделаетexit
сам по себе использует статус выхода последней выполненной команды, который может быть 0.exit 1
, что по соглашению означает неопределенную ошибку.Базовая обработка ошибок
Если ваш исполнитель тестового примера возвращает ненулевой код для неудачных тестов, вы можете просто написать:
Или даже короче:
Или самый короткий:
Чтобы выйти с кодом выхода test_handler:
Расширенная обработка ошибок
Если вы хотите использовать более комплексный подход, у вас может быть обработчик ошибок:
затем вызовите его после запуска тестового примера:
или
Преимущества такого обработчика ошибок
exit_if_error
:if
блоков, которые проверяют коды выхода на наличие ошибокБиблиотека обработки ошибок и ведения журнала
Вот полная реализация обработки ошибок и ведения журнала:
https://github.com/codeforester/base/blob/master/lib/stdlib.sh
Похожие сообщения
__FILE__
,__LINE__
в Bashисточник
Есть еще пара способов решить эту проблему. Предполагая, что одно из ваших требований - запустить сценарий / функцию оболочки, содержащую несколько команд оболочки, и проверить, успешно ли выполняется сценарий, и выдать ошибки в случае сбоев.
Команды оболочки обычно полагаются на возвращаемые коды выхода, чтобы сообщить оболочке, была ли она успешной или неудачной из-за некоторых неожиданных событий.
Итак, то, что вы хотите делать, относится к этим двум категориям
В зависимости от того, что вы хотите сделать, существуют доступные параметры оболочки. В первом случае оболочка предоставляет возможность,
set -e
а во втором вы можете сделатьtrap
наEXIT
Должен ли я использовать
exit
в моем скрипте / функции?С помощью
exit
целом улучшает читаемость. В некоторых подпрограммах, как только вы знаете ответ, вы хотите немедленно выйти из вызывающей процедуры. Если подпрограмма определена таким образом, что она не требует дополнительной очистки после обнаружения ошибки, то незамедлительный выход означает, что вам нужно написать больше кода.Поэтому в случаях, если вам нужно выполнить действия по очистке сценария, чтобы завершить завершение сценария, рекомендуется не использовать
exit
.Следует использовать
set -e
для ошибки при выходе?set -e
была попытка добавить в оболочку "автоматическое обнаружение ошибок". Его цель заключалась в том, чтобы заставить оболочку прерываться каждый раз при возникновении ошибки, но он имеет множество потенциальных ловушек, например,Команды, которые являются частью теста if, неуязвимы. В этом примере, если вы ожидаете, что он прервется при
test
проверке несуществующего каталога, этого не произойдет, он перейдет к условию elseКоманды в конвейере, кроме последнего, неуязвимы. В приведенном ниже примере, потому что код выхода последней выполненной (самой правой) команды считается (
cat
) и он был успешным. Этого можно было бы избежать, установивset -o pipefail
опцию, но это все же предостережение.Рекомендуется к применению -
trap
на выходеВердикт таков: если вы хотите иметь возможность обрабатывать ошибку вместо слепого выхода, вместо использования
set -e
используйте atrap
вERR
псевдосигнале.В
ERR
Ловушка не для запуска кода , когда сама оболочка выходит с ненулевым кодом ошибки, но когда любая команда запуска этой оболочки , которая не является частью состояния (например , в случаеcmd
, илиcmd ||
) завершается со статусом ненулевым .Обычно мы определяем обработчик прерывания, чтобы предоставить дополнительную отладочную информацию о том, какая строка и что вызывает выход. Помните, что код выхода последней команды, вызвавшей
ERR
сигнал, все еще будет доступен в этот момент.и мы просто используем этот обработчик, как показано ниже, поверх скрипта, который не работает
Собрав все это вместе в простом скрипте, содержащемся
false
в строке 15, информация, которую вы получите какtrap
Также варианты независимо от ошибки просто запустить очистку по завершению оболочки (например , ваши выезды с скрипт оболочки), по сигналуEXIT
. Вы также можете захватить несколько сигналов одновременно. Список поддерживаемых сигналов для перехвата можно найти на странице руководства trap.1p - Linux.Еще одна вещь, на которую следует обратить внимание, - это понять, что ни один из предоставленных методов не работает, если вы имеете дело с суб-оболочками, и в этом случае вам может потребоваться добавить свою собственную обработку ошибок.
На суб-оболочке с
set -e
не будет работать.false
Ограничивается суб-оболочки и никогда не будет распространяться на родительской оболочки. Чтобы выполнить здесь обработку ошибок, добавьте свою собственную логику для выполнения(false) || false
То же самое происходит и с
trap
. Приведенная ниже логика не будет работать по причинам, указанным выше.источник
Вот простая ловушка, которая выводит последний аргумент сбоя в STDERR, сообщает о строке, в которой произошел сбой, и выходит из сценария с номером строки в качестве кода выхода. Обратите внимание, что это не всегда отличные идеи, но это демонстрирует творческое применение, которое вы могли бы использовать.
Я поместил это в сценарий с циклом для проверки. Я просто проверяю совпадение с некоторыми случайными числами; вы можете использовать реальные тесты. Если мне нужно внести залог, я вызываю false (что запускает ловушку) с сообщением, которое хочу выбросить.
Для расширенной функциональности позвольте ловушке вызывать функцию обработки. Вы всегда можете использовать оператор case в своем аргументе ($ _), если вам нужно выполнить дополнительную очистку и т. Д. Назначьте var для небольшого синтаксического сахара -
Пример вывода:
Очевидно, вы могли
Есть много возможностей для улучшения дизайна.
К
false
недостаткам можно отнести тот факт, что это некрасиво (следовательно, сахар), а другие вещи, срабатывающие в ловушке, могут выглядеть немного глупо. Тем не менее, мне нравится этот метод.источник
У вас есть 2 варианта: перенаправить вывод скрипта в файл, ввести файл журнала в скрипт и
Здесь вы предполагаете, что сценарий выводит всю необходимую информацию, включая предупреждения и сообщения об ошибках. Затем вы можете перенаправить вывод в файл по вашему выбору.
Приведенная выше команда перенаправляет стандартный вывод и вывод ошибок в файл журнала.
Используя этот подход, вам не нужно вводить файл журнала в скрипт, поэтому логика немного проще.
В свой скрипт добавьте файл журнала, жестко его закодировав:
или передав его параметром:
Рекомендуется добавить метку времени выполнения в файл журнала в верхней части скрипта:
Затем вы можете перенаправить свои сообщения об ошибках в файл журнала.
Это добавит ошибку в файл журнала и продолжит выполнение. Если вы хотите остановить выполнение при возникновении критических ошибок, вы можете
exit
сценарий:Обратите внимание, что
exit 1
означает, что выполнение программы остановлено из-за неопределенной ошибки. Вы можете настроить это, если хотите.Используя этот подход, вы можете настраивать свои журналы и иметь отдельный файл журнала для каждого компонента вашего скрипта.
Если у вас относительно небольшой сценарий или вы хотите выполнить чей-то другой сценарий, не изменяя его, первый подход более подходит.
Если вы хотите, чтобы файл журнала всегда находился в одном месте, это лучший вариант из 2-х. Также, если вы создали большой сценарий с несколькими компонентами, вы можете захотеть регистрировать каждую часть по-разному, и второй подход - ваш единственный вариант.
источник
Я часто считаю полезным написать функцию для обработки сообщений об ошибках, чтобы код в целом был чище.
Это берет код ошибки из предыдущей команды и использует его как код ошибки по умолчанию при выходе из всего скрипта. Он также отмечает время с микросекундами, где это поддерживается (дата GNU
%N
- наносекунды, которые позже мы усекаем до микросекунд).Если первый вариант равен нулю или положительному целому числу, он становится кодом выхода, и мы удаляем его из списка вариантов. Затем мы сообщаем сообщение об ошибке с указанием имени сценария, слова «ERROR» и времени (мы используем расширение параметра для усечения наносекунд до микросекунд или для времени, отличного от GNU, для усечения, например,
12:34:56.%N
до12:34:56
). Двоеточие и пробел добавляются после слова ERROR, но только при наличии сообщения об ошибке. Наконец, мы выходим из скрипта, используя ранее определенный код выхода, запуская любые ловушки как обычно.Некоторые примеры (предположим, что код живет внутри
script.sh
):источник