关于linux:如何在执行bash脚本时显示行号

How to show line number when executing bash script

我有一个测试脚本,它有很多命令,会产生很多输出,我使用set -xset -vset -e,所以当出现错误时脚本会停止。但是,我仍然很难找到执行停止的行以定位问题。是否有一种方法可以在执行每一行之前输出脚本的行号?或者在set -x生成的命令显示前输出行号?或者任何能解决我的脚本行位置问题的方法都会有很大的帮助。谢谢。


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

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

例如,如果脚本显示:

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

因此,执行它将打印行号:

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

http://wiki.bash-hacker.org/scripting/debuggingtips提供了最终的PS4,可以输出您可能需要的所有跟踪信息:

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


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

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

例如:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash      

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

function foo() {
    log"$@"
}

foo"$@"

有关bash变量的详细信息,请参见此处。


没有lineno的外壳的解决方案

在一个相当复杂的脚本中,我不希望看到所有的行号,而是希望控制输出。

定义函数

1
2
3
4
5
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

与引号一起使用,例如

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

输出是

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

如果源文件中这一行的编号是16。

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

还有什么要补充的吗?

当然。你为什么需要这个?你怎么处理这个?你能用这个做什么?这个简单的方法真的足够或有用吗?你为什么要修补这个?

想知道更多吗?阅读关于调试的思考


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

更强大的解决方案:安装bashdbbash调试程序并逐行调试脚本