【发布时间】:2015-03-16 16:06:16
【问题描述】:
我一直在寻找一种方法来在 shell 脚本出错时打印行号。
我遇到了 '-x' 选项,它在运行 shell 脚本时打印该行,但这并不是我想要的。也许我可以在每个退出代码之前做 $LINENO ?有更清洁的方法吗?
我只想要行号,这样我就可以打开 shell 脚本并直接转到解释器发现错误的地方。
【问题讨论】:
我一直在寻找一种方法来在 shell 脚本出错时打印行号。
我遇到了 '-x' 选项,它在运行 shell 脚本时打印该行,但这并不是我想要的。也许我可以在每个退出代码之前做 $LINENO ?有更清洁的方法吗?
我只想要行号,这样我就可以打开 shell 脚本并直接转到解释器发现错误的地方。
【问题讨论】:
使用
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
同样,这在最近的一些 bash 版本中不起作用,它们并不总是在陷阱内正确设置 LINENO。
另一种方法(仅适用于最近的 shell;下面使用一些 bash 4.0 和 4.1 功能)是使用PS4 将每个命令的退出状态和行号发送到专用文件描述符,并使用tail 仅打印在 shell 退出之前给该 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
【讨论】:
$BASH_VERSION 并根据结果使用不同的代码。