环境:GNU bash,版本 3.2.57(1)-release (x86_64-apple-darwin20)
我试图捕获另一个函数的退出,但然后继续执行该程序。在面向对象语言中,您可以捕获异常,然后继续执行而无需重新抛出;这本质上就是我想做的事情。我期待该函数foo()
,exit
但在本例中我想捕获它并继续执行程序。
#!/bin/bash
function doNotExitProgram()
{
echo "Ignoring EXIT"
# Magic happens here
}
trap doNotExitProgram EXIT
function foo()
{
echo "Inside foo()"
exit 170
}
foo
echo "Continue execution here"
预期的:
foo() 内部
忽略 EXIT
在这里继续执行
实际的:
在 foo() 内部
忽略 EXIT
到目前为止尝试过的步骤:
尝试过使用
shopt -s extdebug
,但这似乎不适用于 EXIT。trap - EXIT
里面试过doNotExitProgram()
尝试
trap - EXIT
返回return 0
内部doNotExitProgram()
尝试
trap - EXIT
返回return 1
内部doNotExitProgram()
return 0
里面试过doNotExitProgram()
return 1
里面试过doNotExitProgram()
trap "" EXIT
里面试过doNotExitProgram()
此场景未在tldp.org 上的陷阱或在陷阱手册页。
编辑:如果可以的话不要改变foo()
答案1
或者使用辅助函数:
#!/bin/bash
function doNotExitProgram()
{
echo "Ignoring EXIT"
# Magic happens here
}
function catchExitCode()
{
case $1 in
170 )
doNotExitProgram
;;
esac
}
trap 'catchExitCode $?' DEBUG
function foo()
{
echo "Inside foo()"
return 170
}
foo
echo "Continue execution here"
您可以添加名为 的分支函数catchExitCode
。缺点是如果其他可执行文件返回,它可能会被劫持170
。通过唯一的退出代码,它可以分支逻辑。
答案2
使用x
选项 ( bash -x file
):
+ trap doNotExitProgram EXIT
+ foo
+ echo 'Inside foo()'
Inside foo()
+ exit 170
+ doNotExitProgram
+ echo 'Ignoring EXIT'
Ignoring EXIT
trap doNotExitProgram EXIT
doNotExitProgram
被叫时发生呼叫exit
。当调用时foo
,执行doNotExitProgram
。exit
完成脚本执行所以不执行echo "Continue execution here"
。
解决:
#!/bin/bash
(
function doNotExitProgram()
{
echo "Ignoring EXIT"
# Magic happens here
}
trap doNotExitProgram EXIT
function foo()
{
echo "Inside foo()"
exit 170
}
foo
)
echo "Continue execution here"
结果:
Inside foo()
Ignoring EXIT
Continue execution here
带x
选项:
+ trap doNotExitProgram EXIT
+ foo
+ echo 'Inside foo()'
Inside foo()
+ exit 170
++ doNotExitProgram
++ echo 'Ignoring EXIT'
Ignoring EXIT
+ echo 'Continue execution here'
Continue execution here
您可以在子 shell 中设置陷阱。将输出期望值。
答案3
exit
使用exit
函数隐藏命令
类似于“辅助函数”解决方案,
这不会“继续执行”主脚本
主脚本的“继续执行”需要在 bash 中转到,
另请参阅bash 中有“goto”语句吗?
function evil_function() {
echo "code before exit"
exit 1
echo "code after exit"
}
# shadow the exit command
function exit() {
local rc=$?
if [ -n "$1" ]; then rc=$1; fi
echo "captured exit $rc"
# no, this would continue "code after exit"
#return $rc
# restore the exit command
unset -f exit
# continue script here, then exit
echo "exiting in 5 sec"
sleep 5
exit $rc
}
evil_function
# will not continue here