在从循环调用的函数中未调用Bash陷阱
在从循环内部调用的函数中调用的陷阱不会被调用。如果在循环体中直接调用,则陷阱可以正常工作。如果在循环外部调用相同的函数,则调用陷阱在从循环调用的函数中未调用Bash陷阱,bash,function,bash-trap,Bash,Function,Bash Trap,在从循环内部调用的函数中调用的陷阱不会被调用。如果在循环体中直接调用,则陷阱可以正常工作。如果在循环外部调用相同的函数,则调用陷阱 #!/bin/bash function error_handler() #--------------------- { echo "ERROR STATUS: $?" echo "ERROR COMMAND: $BASH_COMMAND" echo "ERROR STACK:" caller echo "--------
#!/bin/bash
function error_handler() #---------------------
{
echo "ERROR STATUS: $?"
echo "ERROR COMMAND: $BASH_COMMAND"
echo "ERROR STACK:"
caller
echo "---------- end of stack dump ----------"
exit 1
}
function func()
{
echo "..inside func( $1)"
if false
then
true
rv=0
else
false
rv=1
fi
echo "..returning from func( $1), rv=$rv"
return $rv
}
set -o errtrace -o errexit
trap error_handler ERR
for N in 1 2 ; do
echo -e "\nbegin loop $N"
if func $N
then
echo "result of func($N): success"
else
echo "result of func($N): failed"
fi
echo "loop $N is done"
false
done
func 1
func 2
运行上述脚本的实际结果:
开始循环1
…内部函数(1)
..从func(1)返回,rv=1
func(1)的结果:失败
循环1完成
错误状态:1
错误命令:false
错误堆栈:
41./a.sh
----------堆栈结束转储----------
但是我希望陷阱来自func()
中的false
行,而不是程序末尾的false
。
让我们在结尾处注释掉false
。结果是:
begin loop 1
..inside func( 1)
..returning from func( 1), rv=1
result of func(1): failed
loop 1 is done
begin loop 2
..inside func( 2)
..returning from func( 2), rv=1
result of func(2): failed
loop 2 is done
..inside func( 1)
ERROR STATUS: 1
ERROR COMMAND: false
ERROR STACK:
21 ./a.sh
---------- end of stack dump ----------
现在在func()
中调用了陷阱,但在循环1中没有!回路1和回路2均在无陷阱的情况下完成。函数返回后是func 1
,调用了一个陷阱。太晚了
为什么?罪魁祸首不是循环,而是这里的
if
语句:
if func $N
当您在if
语句的测试中使用func
时,ERR
陷阱将在整个测试期间暂停。在func()
内发生的错误不会触发ERR
陷阱,如果启用了errexit
,也不会导致shell退出
引述:
如果失败的命令是紧跟在之后的命令列表的一部分,而或直到关键字,是if
语句中测试的一部分,则不会执行ERR
陷阱,在&&
或|
列表中执行的命令的一部分,除了最后一个&&&
或|
之后的命令,管道中除最后一个命令外的任何命令,或者如果命令的返回值正在使用反转代码>。这些条件与errexit
(-e
)选项所遵循的条件相同
我阅读了手册页面,但是没有明显的迹象表明嵌套命令的陷阱也被挂起。谢谢你的澄清。我可以重写我的示例代码。如果func$N,我可以用func$N替换行;如果[[$?-eq 0]]
,那么如何在函数func
中实现已启用的陷阱?是否只有一种方法:移动func
以分离脚本func.sh
?放置另一个set-o errtrace-o errexit;trap error\u handler ERR
到函数的开头func
没有帮助。我同意,这并不明显。我最近才确切地了解了“测试的一部分”的含义,即在测试完成之前,错误检查是全局暂停的<代码>函数$N;如果…
足以在func
中启用陷阱。