我喜欢使用“set -e”在第一次出现错误时停止。 但如果没有设置“set -x”,则很难判断错误发生在哪一行。
所以,我希望我可以使用trap ERR
来显示错误行。
但是,它失败了,在下面的测试脚本中尝试在 subs1 处停止,但只有 sub2 会被 trap 停止。当退出代码不为 0 时显示错误行号的正确方法是什么?
我的测试脚本如下
#!/bin/bash
subs() {
echo "before false1: $LINENO"
false 1
echo "after false1: $LINENO"
}
subs2() {
echo "before false2: $LINENO"
false 2
}
failed() {
local r=$?
local line=${last_lineno:-$1}
echo "Err: return $r at $line: $BASH_COMMAND"
echo "Trace: " "$@"
exit $r
}
main() {
trap 'failed $LINENO ${BASH_LINENO[@]}' ERR
subs
subs2
echo "end:$LINENO"
}
main "$@"
输出为(在 bash 4.4.12 上)
before false1: 4
after false1: 6
before false2: 9
Err: return 1 at 22: false 2
Trace: 22 25 0
最佳答案
您需要将此指令放在脚本的开头,以使您的 ERR
陷阱由 shell 函数继承。默认情况下,ERR
陷阱不会被继承。
set -E
根据帮助集
:
-E
If set, theERR
trap is inherited by shell functions.
您的完整代码:
#!/bin/bash
set -E
subs() {
echo "before false1: $LINENO"
false 1
echo "after false1: $LINENO"
}
subs2() {
echo "before false2: $LINENO"
false 2
}
failed() {
local r=$?
set -- "${@:1:$(($#-1))}"
# local line=${last_lineno:-$1}
echo "Err: return $r at $1: $BASH_COMMAND"
echo "Trace: " "$@"
exit $r
}
main() {
trap 'failed $LINENO ${BASH_LINENO[@]}' ERR
subs
subs2
echo "end:$LINENO"
}
main "$@"
输出:
$> bash trapScript.sh
before false1: 5
Err: return 1 at 6: false 1
Trace: 6 26 31
关于bash - 为什么bash的子函数中trap ERR失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48740008/