在调用期望返回而不期望返回的函数时,我不清楚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
捕获器吗?
感谢。
答案 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中执行。