灵感来自这个问题:
当条件是命令替换时,如果命令不产生输出,if语句应该做什么?
注意:示例是if $(true); then ...,而不是if true ; then ...
例如,给定:
if $(true) ; then echo yes ; else echo no ; fi
Run Code Online (Sandbox Code Playgroud)
我认为$(true)应该用true命令的输出代替,这没什么.它应该等同于:
if "" ; then echo yes ; else echo no ; fi
Run Code Online (Sandbox Code Playgroud)
打印,no因为没有名称为空字符串的命令,或者这样:
if ; then echo yes ; else echo no ; fi
Run Code Online (Sandbox Code Playgroud)
这是一个语法错误.
但实验表明,如果命令不产生输出,则该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
Run Code Online (Sandbox Code Playgroud)
这是我得到的输出(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'
Run Code Online (Sandbox Code Playgroud)
前四行符合我的预期; 这些$(true)和$(false)线条令人惊讶.
进一步的实验(这里没有显示)表明如果命令$(和)生成输出之间,其退出状态不会影响行为if.
我看到类似的行为(但在某些情况下,不同的错误消息)bash,ksh,zsh,ash,和dash.
我在bash文档或POSIX"Shell Command Language"规范中没有看到任何解释.
(或许我错过了一些明显的东西.)
编辑:根据接受的答案,这是行为的另一个例子:
command='' ; if $command ; then echo yes ; else echo no ; fi
Run Code Online (Sandbox Code Playgroud)
或者,等效地:
command= ; if $command ; then echo yes ; else echo no ; fi
Run Code Online (Sandbox Code Playgroud)
可能需要考虑两个退出代码.首先,这是另外两个应该有用的实验:
# if $(echo true; false) ; then echo yes ; else echo no ; fi
yes
Run Code Online (Sandbox Code Playgroud)
所述内命令与由于故障退出false.但这是无关紧要的,因为命令的输出是非空的,因此执行输出("true")而其退出代码优先.
# if $(echo false; true) ; then echo yes ; else echo no ; fi
no
Run Code Online (Sandbox Code Playgroud)
同样,内部的命令行$( )成功,但输出为no,因为输出("false")优先.
当且仅当输出为空或仅为空格时,命令内部的命令的退出状态$( )是相关的.如果输出为空,则没有要执行的命令列表,因此看起来shell将回退到内部命令的退出状态.
似乎正在发生的是bash保持最后执行的命令的退出状态
这可以解释为什么$(true)和$(false)在一个不同的行为if测试.它们都产生空命令,这些命令不算作执行但它们有不同的退出代码.
只要你使用命令替换上输出了命令,$()试图执行一个输出作为命令和退出代码是尝试,现在最新的一个用于if测试