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


89

我使用的测试脚本包含很多命令,并且会生成大量输出,我使用set -xset -vset -e,所以脚本会在发生错误时停止。但是,我仍然很难定位执行停止在哪一行以定位问题。有没有一种方法可以在执行每行之前输出脚本的行号?还是输出命令产生之前的行号set -x?否则任何可以解决我的脚本行位置问题的方法都将提供很大的帮助。谢谢。

Answers:


159

您提到您已经在使用-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]}(): }'

4
我不知道为什么没有人提到“如何调试shell脚本?” 。这远比仅仅好echo
Suvarna Pattayil 2014年

@VusP同意,echo最好避免不必要的语句。
devnull 2014年

2
我忍不住-x 应该打印行号。或者,也许-nx 应该包括行号。对我来说,这是那些“ WTF”时刻之一……
jww

1
伙计,我希望我能早点知道PS4混合...这会救我很多头痛
Niken

2
\033[0;33m+(${BASH_SOURCE}:${LINENO}):\033[0m ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'对于某些颜色
Ulysse BN

34

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

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

例如:

#!/bin/bash       

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

function foo() {
    log "$@"
}

foo "$@"

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


0

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

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


2
echo在许多情况下,使用周围的东西可能会有所帮助,但是当您尝试将其应用到具有有意义的可解析输出的函数中时,效果会很差。
伊莱兰·马尔卡

1
@EliranMalka公平点。在这种情况下,您可能会回应stderr:echo "foo" >&2
hek2mgl

1
...如果目的是本质上具有诊断性的消息,则在所有情况下都应向stderr回显。
查尔斯·达菲

0

不带LINENO的外壳的解决方法

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

定义功能

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

将其与诸如

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

输出为

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

如果源文件中此行的编号为16。

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

还有什么要补充的吗?

当然。你为什么需要这个?您如何处理这个?你能做什么呢?这种简单的方法真的足够或有用吗?您为什么要完全修改呢?

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.