bash – 为什么`if $(true);然后… fi成功?

灵感来自 this question

当条件是命令替换时,if语句应该怎么做,命令不会产生输出?

注意:例如,如果$(true);那么…,不是如果真的;然后 …

例如,给出:

if $(true) ; then echo yes ; else echo no ; fi

我会认为,$(true)应该被真正的命令的输出所替代,这是没有的。那么应该等同于:

if "" ; then echo yes ; else echo no ; fi

它不打印,因为没有命名的名称是空字符串,或者是:

if ; then echo yes ; else echo no ; fi

这是一个语法错误。

但是实验表明,如果命令不产生任何输出,则if语句根据命令的状态而不是其输出将其视为true或false。

这是一个演示行为的脚本:

#!/bin/bash

echo -n 'true:          ' ; if true          ; then echo yes ; else echo no ; fi
echo -n 'false:         ' ; if false         ; then echo yes ; else echo no ; fi
echo -n '$(echo true):  ' ; if $(echo true)  ; then echo yes ; else echo no ; fi
echo -n '$(echo false): ' ; if $(echo false) ; then echo yes ; else echo no ; fi
echo -n '$(true):       ' ; if $(true)       ; then echo yes ; else echo no ; fi
echo -n '$(false):      ' ; if $(false)      ; then echo yes ; else echo no ; fi
echo -n '"":            ' ; if ""            ; then echo yes ; else echo no ; fi
echo -n '(nothing):     ' ; if               ; then echo yes ; else echo no ; fi

这是我得到的输出(Ubuntu 11.04,bash 4.2.8):

true:          yes
false:         no
$(echo true):  yes
$(echo false): no
$(true):       yes
$(false):      no
"":            ./foo.bash: line 9: : command not found
no
./foo.bash: line 10: syntax error near unexpected token `;'
./foo.bash: line 10: `echo -n '(nothing):     ' ; if               ; then echo yes ; else echo no ; fi'

前四行表现如我所料; $(true)和$(false)行令人惊讶。

进一步的实验(此处未显示)表示如果$(和)之间的命令产生输出,则其退出状态不会影响if的行为。

在bash,ksh,zsh,ash和dash中,我看到类似的行为(在某些情况下是不同的错误信息)。

我在bash文档或POSIX“Shell命令语言”规范中看不到任何内容,以解释这一点。

(或者也许我缺少一些明显的东西)

编辑:鉴于接受的答案,这里是另一个行为的例子:

command='' ; if $command ; then echo yes ; else echo no ; fi

或等效地:

command=   ; if $command ; then echo yes ; else echo no ; fi
language spec第2.9.1节。第一部分的最后一句是:

If there is a command name,execution shall continue as described in Command Search and Execution . If there is no command name,but the command contained a command substitution,the command shall complete with the exit status of the last command substitution performed. Otherwise,the command shall complete with a zero exit status.

$(true)正在扩展为空字符串。 shell解析空字符串,发现没有给出命令,并遵循上述规则。

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...