Bash函数退出时的陷阱

34
在bash中,是否有可能在函数退出时调用某个命令?我的意思是类似于以下内容:
function foo
{
    # something like this maybe?
    trap "echo \"exit function foo\"" EXIT

    # do something
}

foo

我希望退出函数"foo"的结果被打印出来。


我需要这个东西来处理不同的情况,因为我的陷阱从bash_profile函数中泄漏到了我的正常shell中,我需要在函数终止之前捕获并重置它们。无论如何,非常感谢你的提问! - Scott Anderson
不用谢 :) - bercik
2个回答

45

是的,你可以捕获 RETURN

$ function foo() {
>   trap "echo finished" RETURN
>   echo "doing some things"
> }
$ foo

将会展示

doing some things
finished

trap内建命令的man bash描述如下:

如果sigspec为RETURN,则每次一个由内置命令.或source执行的shell函数或脚本执行完毕时,都会执行命令参数。


1
这个函数的返回值也能被捕获吗? - bercik
3
如果你想根据函数的返回代码采取不同的操作,你需要使用条件语句,如ifcase。请注意,trap设置的处理程序是全局的,因此在调用foo时会替换任何先前存在的RETURN陷阱(假设foo的主体是一个{...}命令;foo () ( trap ...; )将不影响调用上下文)。 - chepner
1
话虽如此,您可以捕获ERR以触发任何非零返回状态除了捕获RETURN的陷阱。您只是不能为返回代码1和返回代码2设置不同的陷阱。 - chepner
1
@bercik,不行。即使在使用隐式返回时,trap命令中的$?也无法包含函数作用域内执行的最后一个命令的成功值。如果您想要跟踪函数执行的开始/结束和结果,则还有其他替代方法可以使用,但不是陷阱。 - Aaron
1
当脚本退出时,使用EXIT调用处理程序而不是函数。 - kyb
显示剩余4条评论

3

关于使用Ctrl+c退出(不需要声明另一个函数来退出):

#!/bin/bash
function do_stuff() {
  function do_stuff_end() {
    # the code for exiting the function here
    echo "<the code for exiting the function here>"
    unset -f do_stuff_end
    trap "$trap_sigint" SIGINT
    return
  }
  trap_sigint="$(trap -p SIGINT)"
  trap "do_stuff_end; return" SIGINT
  # the code for the function here
  echo "<the code for the function here>"
  do_stuff_end
}

注意:前面的代码“只是”能够工作,但需要改进,考虑除SIGINT信号外其他信号的影响。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接