Как найти номер строки в Bash, где произошла ошибка?
пример
Я создаю следующий простой скрипт с номерами строк, чтобы объяснить, что нам нужно. Скрипт будет копировать файлы из
cp $file1 $file2
cp $file3 $file4
При сбое одной из cp
команд функция завершается с выходом 1 . Мы хотим добавить в функцию возможность также печатать ошибку с номером строки (например, 8 или 12).
Это возможно?
Пример сценария
1 #!/bin/bash
2
3
4 function in_case_fail {
5 [[ $1 -ne 0 ]] && echo "fail on $2" && exit 1
6 }
7
8 cp $file1 $file2
9 in_case_fail $? "cp $file1 $file2"
10
11
12 cp $file3 $file4
13 in_case_fail $? "cp $file3 $file4"
14
set -x
и / илиset -v
отслеживать, что было выполнено. Не совсем то, что вы просили, но, вероятно, это тоже будет полезно.Ответы:
Вместо того, чтобы использовать вашу функцию, я бы использовал этот метод:
Это работает путем перехвата ERR и последующего вызова
failure()
функции с текущей командой номер строки + команда bash, которая была выполнена.пример
Здесь я не принял никакого ухода , чтобы создать файлы,
f1
,f2
,f3
, илиf4
. Когда я запускаю вышеуказанный скрипт:Это терпит неудачу, сообщая номер строки плюс команда, которая была выполнена.
источник
В дополнение к
LINENO
текущему номеру строки, существуют массивыBASH_LINENO
иFUNCNAME
(иBASH_SOURCE
), которые содержат имена функций и номера строк, из которых они вызваны.Таким образом, вы можете сделать что-то вроде этого:
Запуск, который напечатает
Если вы используете
set -e
илиtrap ... ERR
для автоматического обнаружения ошибок, обратите внимание, что у них есть некоторые предупреждения. Также сложнее включить описание того, что скрипт делал в то время (как вы делали в вашем примере), хотя это может быть более полезным для обычного пользователя, чем просто номер строки.Посмотрите, например, на эти проблемы
set -e
и другие:источник
Bash имеет встроенную переменную,
$LINENO
которая заменяется текущим номером строки в выражении, так что вы можете сделатьВы также можете попробовать использовать то,
trap ... ERR
что выполняется при сбое команды (если результат не проверен). Например:Затем, если такая команда
cp $file1 $file2
потерпит неудачу, вы получите сообщение об ошибке с номером строки и выходом. Вы также найдете команду с ошибкой в переменной$BASH_COMMAND
(но не перенаправления и т. Д.).источник