Я пытаюсь создать несколько отчетов об ошибках, используя Trap для вызова функции по всем ошибкам:
Trap "_func" ERR
Можно ли узнать, с какой линии был отправлен сигнал ERR? Оболочка Баш.
Если я это сделаю, я смогу прочитать и сообщить, какая команда использовалась, и записать / выполнить некоторые действия.
Или, может быть, я все это неправильно?
Я проверил со следующим:
#!/bin/bash
trap "ECHO $LINENO" ERR
echo hello | grep "asdf"
И $LINENO
возвращается 2. не работает.
bash
shell-script
error-handling
trap
Mechaflash
источник
источник
bashdb
. Кажется, что первый аргументtrap
может содержать переменные, которые оцениваются в нужном контексте. Такtrap 'echo $LINENO' ERR'
должно работать.trap 'echo $LINENO' ERR
. Первым аргументомtrap
является всяecho $LINENO
жесткая цитата. Это в Баш.trap 'echo $LINENO' ERR
, с одинарными кавычками, а не с двойными. С помощью команды, которую вы написали,$LINENO
раскрывается при разборе строки 2, поэтому ловушкаecho 2
(точнееECHO 2
, будет выводитьсяbash: ECHO: command not found
).Ответы:
Как указано в комментариях, ваша цитата неверна. Вам нужны одинарные кавычки, чтобы предотвратить
$LINENO
расширение при первом анализе строки ловушки.Это работает:
Запуск это:
источник
echo hello | grep foo
кажется, не выдает ошибку для меня. Я что-то неправильно понимаю?grep
состояние выхода равно 0, если совпадение было, 1, если совпадения не было, и> 1 для ошибки. Вы можете проверить поведение в вашей системе сecho hello | grep foo; echo $?
Вы также можете использовать встроенную в Caller команду:
он также печатает имя файла:
источник
Мне действительно нравится ответ, данный @Mat выше. Основываясь на этом, я написал небольшой помощник, который дает немного больше контекста для ошибки:
Мы можем проверить скрипт на наличие строки, которая вызвала сбой:
Вот это в небольшом тестовом скрипте:
Когда мы запускаем его, мы получаем:
источник
$(caller)
данные для определения контекста, даже если ошибка не в текущем скрипте, а в одном из его импортов. Очень хорошо, хотя!Вдохновленный другим ответом, вот более простой контекстный обработчик ошибок:
Вы также можете использовать awk вместо tail & head, если это необходимо.
источник
Вот еще одна версия, вдохновленная @sanmai и @unpythonic. Он показывает строки сценария вокруг ошибки, с номерами строк и статусом выхода - используя tail & head, так как это кажется проще, чем решение awk.
Показывая это в виде двух строк здесь для удобства чтения - вы можете объединить эти строки в одну, если хотите (сохраняя
;
):Это работает очень хорошо с
set -euo pipefail
( неофициальный строгий режим ) - любая неопределенная ошибка переменной дает номер строки без запускаERR
псевдосигнала, но другие случаи действительно показывают контекст.Пример вывода:
источник
Да,
LINENO
иBASH_LINENO
переменные supper полезны для получения линии сбоя и линий, которые приводят к нему.Нет, просто отсутствует
-q
опция с grep ...... С
-q
опциейgrep
вернемся0
заtrue
и1
заfalse
. И в Баш этоtrap
неTrap
...Вот ловушка, которая может оказаться полезной для отладки вещей, которые имеют немного большую цикломатическую сложность ...
failure.sh
... и пример сценария использования для выявления тонких различий в том, как установить вышеупомянутую ловушку для трассировки функций ...
example_usage.sh
Вышесказанное проверено на Bash версии 4+, поэтому оставьте комментарий, если требуется что-то для версий до четырех, или откройте проблему, если она не может перехватить сбои в системах с минимальной версией четыре.
Основными блюдами являются ...
-E
вызывает ошибки в функции к пузыриться-o functrace
причин позволяет больше многословия, когда что-то внутри функции не удаетсяОдиночные кавычки используются вокруг вызова функции, а двойные кавычки - вокруг отдельных аргументов.
Ссылки на
LINENO
иBASH_LINENO
передаются вместо текущих значений, хотя это может быть сокращено в более поздних версиях, связанных с ловушкой, так что последняя строка ошибки превращает ее в выводЗначения
BASH_COMMAND
и exit status ($?
) передаются, во-первых, чтобы получить команду, которая возвратила ошибку, и во-вторых, чтобы убедиться, что ловушка не срабатывает при статусах без ошибок.И хотя другие могут не согласиться, я считаю, что проще создать выходной массив и использовать printf для печати каждого элемента массива в отдельной строке ...
... также
>&2
бит в конце приводит к тому, что ошибки идут туда, куда должны (стандартная ошибка), и позволяет фиксировать только ошибки ...Как показано в этих и других примерах переполнения стека, существует множество способов создания средства отладки с использованием встроенных утилит.
источник