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解析空字符串,发现没有给出命令,并遵循上述规则。

相关文章

普通模式 >G 增加当前行到文档末尾处的缩紧层级 $ 移动到本行的末尾 . 相当于一个...
原文连接: https://spacevim.org/cn/layers/lang/elixir/ 模块简介 功能特性 启用模块 快捷键 语言专属...
原文连接: https://spacevim.org/cn/layers/lang/dart/ 模块简介 功能特性 依赖安装及启用模块 启用模...
 =   赋值操作符,可以用于算术和字符串赋值 +        加法计算     -        减法运算...
1.根据包名来查看指定的APP指定数据 adb shell "top | grep com.xxx.xxx" 由于这样打印出来的数...
ctrl+F 向下翻页 ctrl+B 向下翻页 u 取消最近一次操作 U 取消当前行的操作 ZZ 保存当前内容并退出 gg 跳...