如何在 Bash 中找到发生错误的行号?
例子
我创建了以下带有行号的简单脚本来解释我们需要什么。该脚本将从
cp $file1 $file2
cp $file3 $file4
当其中一个cp
命令失败时,该函数将以 exit 1 退出。我们希望向函数添加功能,以便还使用行号(例如,8 或 12)打印错误。
这可能吗?
示例脚本
1 #!/bin/bash
2
3
4 function in_case_fail {
5 [[ $1 -ne 0 ]] && echo "fail on $2" && exit 1
6 }
7
8 cp $file1 $file2
9 in_case_fail $? "cp $file1 $file2"
10
11
12 cp $file3 $file4
13 in_case_fail $? "cp $file3 $file4"
14
我不会使用您的功能,而是使用此方法:
这通过捕获 ERR 然后
failure()
使用当前行号 + 执行的 bash 命令调用该函数来工作。例子
在这里,我没有注意创建文件、
f1
、f2
、f3
或f4
. 当我运行上面的脚本时:它失败了,报告行号加上执行的命令。
除了
LINENO
包含当前行号之外,还有包含函数名称和调用它们的行号的BASH_LINENO
和FUNCNAME
(and ) 数组。BASH_SOURCE
所以你可以做这样的事情:
运行会打印
如果您使用
set -e
或trap ... ERR
来自动检测错误,请注意它们有一些警告。包含脚本当时正在做什么的描述也更难(就像您在示例中所做的那样),尽管这对普通用户可能比仅行号更有用。有关与其他问题的问题,请参见例如这些
set -e
:Bash 有一个内置变量
$LINENO
,它在语句中被当前行号替换,所以你可以这样做您也可以尝试使用
trap ... ERR
which 在命令失败时运行(如果未测试结果)。例如:然后,如果类似命令
cp $file1 $file2
失败,您将收到带有行号和退出的错误消息。您还会在变量中找到错误的命令$BASH_COMMAND
(尽管没有任何重定向等)。我决定使用以下内容,其中包括一个堆栈跟踪,就
list of fns [list of line numbers]
好像脚本在一个函数中一样,或者脚本行号。还要感谢以前的答案,我在进行了一些实验以处理基于 fn 和非基于 fn 的脚本后对其进行了扩展。所以一个简单的命令失败,看起来像:
和嵌套函数(hello1 调用 hello2):
我偶尔会报告退出状态,它会为您提供额外的信息,并且与其他所有人不同,我想要脚本的完整路径名。
需要进一步的工作来报告由于信号而退出。