在bash中使用trap EXIT后如何继续执行?

在bash中使用trap EXIT后如何继续执行?

环境: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

到目前为止尝试过的步骤:

  1. 尝试过使用shopt -s extdebug,但这似乎不适用于 EXIT。

  2. trap - EXIT里面试过doNotExitProgram()

  3. 尝试trap - EXIT返回return 0内部doNotExitProgram()

  4. 尝试trap - EXIT返回return 1内部doNotExitProgram()

  5. return 0里面试过doNotExitProgram()

  6. return 1里面试过doNotExitProgram()

  7. 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 EXITdoNotExitProgram被叫时发生呼叫exit。当调用时foo,执行doNotExitProgramexit完成脚本执行所以不执行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

相关内容