如果命令失败,为什么"if"语句的退出代码不是失败?



我以为我很了解shell,但是我被意想不到的行为咬了。

考虑以下代码:

#!/bin/bash
foo()
{
if false
then
echo success
else
return
fi
}
foo || echo failure

现在,乍一看,人们会认为else return部分是多余的,但它不是。代码原样输出failure,但是当被引用的部分被删除时,则nothing输出。

bash手册解释(对于if):

退出状态为最后执行的命令的退出状态,如果没有条件测试为真,则为零。

当命令失败时,我期望if失败。想象一下,在echo success所在的位置,实际上有一些依赖的命令,这些命令只有在主命令(这里是false)成功时才有意义。

这种意外行为背后的逻辑是什么?

参见bash-4.4。相关:https://stackoverflow.com/a/63884458/6607497

if语句实际上从未与return语句完成;函数立即返回,退出状态由return提供。该退出状态是return之前退出的最后一个命令的状态,即false

如果没有return,if不会完成,并且如文档所述,如果if子句或任何elif子句中的条件都没有计算为真,则if命令的退出状态定义为0。这是有道理的,因为if语句成功地确定了ifelif块都不需要执行。

bash手册解释(对于return):

返回
return [n]

导致shell函数停止执行并将值n返回给调用者。如果未提供n,则返回值为退出状态最后执行的命令

:

if false
then
echo success
else
# The LAST command is `false` with exit status 1 !
return  # Returns 1 - returns failure!
fi

最新更新