在执行 shell 脚本时,如何知道它正在执行的行号?

16

在执行shell脚本时,如何知道它正在执行哪一行?是否需要编写一个包装器,在其中可以从shell脚本中执行另一个shell脚本,并知道它正在执行哪一行。

3个回答

22

你可以设置 PS4 变量来使得 set -x 命令的输出包含行号:

PS4=':${LINENO}+'
set -x

这将在每行执行时将行号放在行前:

:4+command here
:5+other command

PS4中,变量展开后需要加上一些特殊字符(例如我的示例中的+),因为最后一个字符会被重复使用来表示嵌套深度。也就是说,如果你调用一个函数,并且该函数调用另一个命令,则set -x的输出将如下所示:

:3+++command run within a function called from a function
:8++command run within a function
:19+line after the function was called
如果你的脚本需要多个文件运行,你可能需要包含 BASH_SOURCE 变量而不是仅仅使用 LINENO(假设这确实是一个 Bash 脚本,而不是 /bin/sh -- 确保你的脚本以 #!/bin/bash 开始!)。
PS4=':${BASH_SOURCE}:${LINENO}+'
set -x

2
你说“最后一个字符被重复以显示嵌套深度”,但是man bash却说:“PS4的第一个字符会根据需要重复多次,以指示多个间接级别。” - Lucian Wischik
在这个上下文中,你理解的“间接级别”是什么意思?用那种方式描述堆栈帧深度确实不是最直接的术语,但它仍然是手头的含义。 - Charles Duffy
@LucianWischik,...另请参阅http://wiki.bash-hackers.org/scripting/debuggingtips#use_shell_debug_output - Charles Duffy

6
Bash 有一个特殊的变量 $LINENO,可以实现你所需的功能。
#!/bin/bash
echo "$LINENO"
echo "$LINENO"
echo "$LINENO"

示例:

$ ./lineno
2
3
4

5
#!/bin/sh -x

会报告代码执行的行(明确一下,使用 -x 选项)。它不会给你 行号,但会报告实际行。

一种可行的但更繁琐的方法是使用 trap 处理程序,如文档 这里所述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接