如何退出期望返回的bash函数

时间:2014-12-30 18:02:26

标签: bash return exit

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

例如,在以下repro中:

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

我们看到了输出:

$ ./z.bash 
Flag 1

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

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

输出显示该函数显然不会退出shell。

$ ./z.bash
We should never see this.

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

感谢。

2 个答案:

答案 0 :(得分:4)

执行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."

退出状态为非零,因此主机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."

输出:

Flag 1

答案 1 :(得分:4)

致电时:

foo=$(exitfunc)

或老式:

foo=`exitfunc`

函数exitfunc由于命令替换而在forked子shell中执行,因此exit仅终止子shell或子shell而不是当前shell。因此,在echo赋值之后打印foo语句,因为此echo在当前shell中执行。