为什么`如果$(真);那么...... fi`成功吗? [英] Why does `if $(true) ; then ... fi` succeed?

查看:137
本文介绍了为什么`如果$(真);那么...... fi`成功吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

href=\"http://stackoverflow.com/questions/8965509/why-if-ps-aux-grep-always-succeeds-in-bash\">这个问题:

在条件就是该命令不产生输出命令替换你应该if语句呢?

注意:的例子是如果$(真);然后... ,而不是如果为true;然后...

例如,给出:

 如果$(真);然后是呼应;别的不呼应;科幻

我认为 $(真)应该由真正命令的输出,这是被替换没有。那么它应该是等效于这样的:

 如果;然后是呼应;别的不呼应;科幻

这版画没有因为没有命令其名称为空字符串,或者这样:

 如果;然后是呼应;别的不呼应;科幻

这是一个语法错误。

但实验显示,如果该命令不产生输出时,如果语句把它当作真或假取决于命令的状态,而不是它的输出。

下面是一个演示行为的脚本:

 #!/斌/庆典呼应-n'真:';如果属实          ;然后是呼应;别的不呼应;科幻
呼应-n错误:';如果为false;然后是呼应;别的不呼应;科幻
呼应-n$(回声真):';如果$(回声真);然后是呼应;别的不呼应;科幻
呼应-n$(回声假)';如果$(回声假);然后是呼应;别的不呼应;科幻
呼应-n'$(真):';如果$(真);然后是呼应;别的不呼应;科幻
呼应-n'$(假)';如果$(假);然后是呼应;别的不呼应;科幻
呼应-n':';如果;然后是呼应;别的不呼应;科幻
呼应-n(无):';如果;然后是呼应;别的不呼应;科幻

和这里的输出我得到(Ubuntu的11.04,庆典​​4.2.8):

 真:是的
假:无
$(回声真):是
$(回声假):无
$(真):是
$(假):无
:./foo.bash:9号线:命令未找到
没有
./foo.bash:第10行:附近意外的标记'语法错误;
./foo.bash:第10行:`回声-n'(无):';如果;然后是呼应;别的不呼应;科幻

前四行表现为我期望;在 $(真) $(假)行是令人惊讶的。

进一步的实验(这里没有显示)表明,如果 $的命令(产生输出,其退出状态不影响行为的如果

我看到类似的行为与庆典 KSH ,<$ C(但不同的错误在某些情况下,消息) $ C>的zsh ,灰分破折号

我什么也看不到在bash文档中,还是在POSIXShell命令语言的规范,来解释这一点。

(也许我缺少明显的东西。)

编辑:在接受答案的光,这里的行为的一个例子:

 命令='';如果$命令;然后是呼应;别的不呼应;科幻

或等价地:

 命令=;如果$命令;然后是呼应;别的不呼应;科幻


解决方案

查看的语言规范。首节最后一句:


  

如果有一个命令名称,如命令搜索与执行所描述的执行将继续。如果没有命令名称,但该命令包含一个命令替换,命令应执行的最后一个命令替换的退出状态完成。否则,该命令应以零退出状态完成。


$(真)正在扩大为空字符串。壳解析空字符串,发现没有命令,并且遵循上述规则。

Inspired by this question:

What should an if statement do when the condition is a command substitution where the command produces no output?

NOTE: The example is if $(true); then ..., not if true ; then ...

For example, given:

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

I would think that $(true) should be replaced by the output of the true command, which is nothing. It should then be equivalent to either this:

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

which prints no because there is no command whose name is the empty string, or to this:

if ; then echo yes ; else echo no ; fi

which is a syntax error.

But experiment shows that if the command produces no output, the if statement treats it as true or false depending on the status of the command, rather than its output.

Here's a script that demonstrates the behavior:

#!/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

and here's the output I get (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'

The first four lines behave as I'd expect; the $(true) and $(false) lines are surprising.

Further experiment (not shown here) indicates that if the command between $( and ) produces output, its exit status doesn't affect the behavior of the if.

I see similar behavior (but different error messages in some cases) with bash, ksh, zsh, ash, and dash.

I see nothing in the bash documentation, or in the POSIX "Shell Command Language" specification, to explain this.

(Or perhaps I'm missing something obvious.)

EDIT : In light of the accepted answer, here's another example of the behavior:

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

or, equivalently:

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

解决方案

See section 2.9.1 of the language spec. The last sentence of the first section reads:

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.

The $(true) is expanding to the empty string. The shell parses the empty string and finds that no command is given and follows the above rule.

这篇关于为什么`如果$(真);那么...... fi`成功吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆