如何退出需要返回的 bash 函数

Ben*_*ett 2 bash return exit

我不完全清楚在调用期望返回与不期望返回的函数时 bash 的 exit 关键字是如何/为什么不一致的。

例如,在以下重现中:

#!/bin/bash
exitfunc()
{
  echo "Flag 1"
  exit
}
exitfunc
echo "We should never see this."
Run Code Online (Sandbox Code Playgroud)

我们看到输出:

$ ./z.bash 
Flag 1
Run Code Online (Sandbox Code Playgroud)

然而,在这个小小的修改中:

#!/bin/bash
exitfunc()
{
      echo "Flag 1"
      exit
}
foo=exitfunc
echo "We should never see this."
Run Code Online (Sandbox Code Playgroud)

输出显示该函数显然没有退出 shell。

$ ./z.bash
We should never see this.
Run Code Online (Sandbox Code Playgroud)

看来Flag 1第二个版本中的 是存储在 foo 中的值,可能用于存储错误代码。我的问题是,为什么exit在以这种方式调用的函数中会有这种行为?当函数需要返回时,它是否会打开一个新的 shell?如何正确退出这些功能之一?我是否只需要检查捕获器的输出值fooexit一直包含到调用堆栈中?

谢谢。

Tom*_*ech 5

当您这样做时foo=exitfunc,您是将一个字符串分配exitfunc给变量foo,而不是执行一个函数。为了执行该函数,您应该foo=$(exitfunc)这样做。然后该变量foo将包含函数的输出“Flag 1”。这称为命令替换。

对 的调用exit将终止执行该函数的子 shell,而不是调用该函数的 shell。为了退出主机 shell,您可以执行以下操作:

#!/bin/bash
exitfunc()
{
      echo "Flag 1"
      exit 1
}
foo=$(exitfunc) || exit
echo "We never see this."
Run Code Online (Sandbox Code Playgroud)

退出状态不为零,因此主机 shell 在最后一行之前退出。

函数的返回码存储在变量中$?,所以如果你想在退出前使用$foo,你可以这样做:

#!/bin/bash
exitfunc()
{
      echo "Flag 1"
      exit 1
}
foo=$(exitfunc)
e=$?
echo "$foo"
if [ $e -ne 0 ]; then exit; fi
echo "We never see this."
Run Code Online (Sandbox Code Playgroud)

输出:

Flag 1
Run Code Online (Sandbox Code Playgroud)