2015-03-16 5 views
2

Я искал способ распечатать номер строки внутри скрипта оболочки, когда он выйдет из строя.Шелл сценарий номер строки печати, когда он ошибается

Я столкнулся с опцией -x, которая печатает строку при запуске сценария оболочки, но это не совсем то, что я хочу. Может быть, я могу сделать $ LINENO перед каждым кодом выхода? Есть ли более чистый способ сделать это?

Мне просто нужен номер строки, чтобы я мог открыть сценарий оболочки и сразу перейти туда, где интерпретатор понял ошибку.

ответ

4

Использование

PS4=':$LINENO+' 

добавит номер строки к выходу set -x.


Если вы только хотите напечатать, что на ошибки, есть некоторый риск нарваться ошибок в последних переводчиков. Тем не менее, вы можете попробовать следующее (первый дан в this previous answer):

error() { 
    local parent_lineno="$1" 
    local message="$2" 
    local code="${3:-1}" 
    if [[ -n "$message" ]] ; then 
    echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}" 
    else 
    echo "Error on or near line ${parent_lineno}; exiting with status ${code}" 
    fi 
    exit "${code}" 
} 
trap 'error ${LINENO}' ERR 

Опять же, это не будет работать на некоторых последних сборках Баш, которые не всегда имеют LINENO установить правильно внутри ловушки.


Другой подход (который будет только работы на последних оболочки, ниже использует некоторый Баш 4.0 и 4.1 функции) заключается в использовании PS4 испускать статус выхода и номер строки каждой команды на специальный дескриптор файла и использовать tail печатать только последнюю строку, данную, что FD перед выходом из оболочки:

exec {BASH_XTRACEFD}> >(tail -n 1) # send set -x output to tail -n 1 
PS4=':At line $LINENO; prior command exit status $?+' 
set -x 
+0

это рискованно, если этот сценарий оболочки не удается из-Баша версий, так как он будет повторно использоваться в различных оболочках. Думаю, я поеду с первым вариантом PS4 = ': $ LINENO +'. Мне действительно не нужны настоящие строки, потому что он загромождает консоль, но если это безопасный способ, который работает везде, пусть будет так. – user2441441

+0

Вы всегда можете проверить '$ BASH_VERSION' и использовать другой код в зависимости от результата. –

+0

@ user2441441, ... поочередно, легко сделать последний код работать со старыми версиями bash *, если вам не нужен stderr для чего-либо еще *. –

Смежные вопросы