执行 bash 脚本时如何显示行号

我有一个测试脚本,其中有很多命令,并将生成大量的输出,我使用 set -xset -vset -e,所以脚本将停止时,错误发生。然而,我仍然很难找到执行停止的那一行来定位问题。 是否有一种方法可以在每行执行之前输出脚本的行号? 或者输出 set -x生成的命令展示前的行号? 或任何方法,可以处理我的脚本行定位问题将是一个很大的帮助。 谢谢。

89720 次浏览

简单(但强大)的解决方案: 将 echo放在你认为会导致问题的代码周围,一行一行地移动 echo,直到消息不再出现在屏幕上——因为脚本之前因为一个错误而停止。

更强大的解决方案: 安装 bashdb bash 调试器并逐行调试脚本

在 Bash 中,$LINENO包含当前正在执行脚本的行号。

如果需要知道调用函数的行号,请尝试 $BASH_LINENO。注意,这个变量是一个数组。

例如:

#!/bin/bash


function log() {
echo "LINENO: ${LINENO}"
echo "BASH_LINENO: ${BASH_LINENO[*]}"
}


function foo() {
log "$@"
}


foo "$@"

See here for details of Bash variables.

你提到你已经在使用 -x了。变量 PS4表示当设置 -x选项并默认为 :后跟空格时,在回显命令行之前打印的提示符。

您可以更改 PS4以发出 LINENO(当前正在执行的脚本或 shell 函数中的行号)。

例如,如果您的脚本如下:

$ cat script
foo=10
echo ${foo}
echo $((2 + 2))

如此执行将打印行号:

$ PS4='Line ${LINENO}: ' bash -x script
Line 1: foo=10
Line 2: echo 10
10
Line 3: echo 4
4

Http://wiki.bash-hackers.org/scripting/debuggingtips 给出了最终的 PS4,它可以输出跟踪可能需要的所有内容:

export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

没有 LINENO 的 shell 的解决方案

In a fairly sophisticated script I wouldn't like to see all line numbers; rather I would like to be in control of the output.

定义一个函数

echo_line_no () {
grep -n "$1" $0 |  sed "s/echo_line_no//"
# grep the line(s) containing input $1 with line numbers
# replace the function name with nothing
} # echo_line_no

Use it with quotes like

echo_line_no "this is a simple comment with a line number"

输出是

16   "this is a simple comment with a line number"

如果源文件中此行的数目为16。

这基本上回答了没有 LINENO的 ash 或其他 shell 的用户的问题 执行 bash 脚本时如何显示行号

还有什么要补充的吗?

当然。你要这个干什么?你是怎么做到的?你能用这个做什么?这种简单的方法真的足够有用吗?你到底为什么想要修补这个?

想知道更多吗

价值 $LINENO 的 PS4是你需要的,

例如,下面的脚本(myScript.sh) :

       #!/bin/bash -xv
PS4='${LINENO}: '
echo "Hello"
echo "World"

产出将是:

  ./myScript.sh
+echo Hello
3 : Hello
+echo World
4 : World