我喜欢使用'set -e'在第一次出现错误时停止。 但是,如果未设置'set -x',则很难判断错误发生在哪一行。
所以,我希望我可以使用trap ERR
来显示错误行。
但是,它失败了,在下面的测试脚本中尝试停在subs1,但只有sub2会被陷阱停止。当退出代码不是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
答案 0 :(得分:2)
您需要在脚本开头使用此指令,以使shell函数继承您的ERR
陷阱。默认情况下,ERR
陷阱不会被继承。
set -E
根据help set
:
-E
如果设置,则shell函数将ERR
陷阱继承。
您的完整代码:
#!/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