为什么这个if语句在bash中被评估为true?

时间:2017-07-21 13:25:05

标签: bash

# prints "here" when run in bash
if [[ ((9 > 220)) ]]; then echo "here"; fi

我很困惑为什么上面的if语句被评估为true。不会((9 > 220))评估为false会导致if语句错误吗? 下面的代码表现如预期。我很困惑为什么在双括号中使用双括号"如果"虽然不是在上面工作。

# doesn't print anything
if ((9 > 220)); then echo "here"; fi

4 个答案:

答案 0 :(得分:1)

这是因为使用双括号使其成为词典比较。这意味着它会检查哪个序列更长,就像按字母顺序排序一样。有关词典比较的更多信息here

答案 1 :(得分:1)

在条件构造中,这两个compound commands之间存在根本区别。

[[ expression ]]复合命令

在您的第一个示例中,您使用[[ expression ]]命令:

if [[ ((9 > 220)) ]]; then echo "here"; fi

其中括号仅被视为分组运算符,用于覆盖其他运算符的正常优先级(如!&&||,{{ 1}},>-gt等)。在这种情况下,-e运算符是大于。

的词典

>

中很好地描述了这一点
  

man bash

     

根据条件表达式表达式的评估,返回0或1的状态。表达式由下面在条件表达式下描述的原色组成。单词拆分和路径名扩展   没有在[[和]]之间的单词上执行;执行波形扩展,参数和变量扩展,算术扩展,命令替换,进程替换和引用删除。 [[ expression ]]等条件运算符必须不加引号才能被识别为原色。

     

-f一起使用时,[[<运算符按字典顺序排序,使用当前区域设置。

因此,要比较>复合命令中的整数,可以使用conditional expression operators[[test命令使用的arithmetic expansion。例如:

[

结果与if [[ 9 -gt 220 ]]; then echo "here"; fi 运算符与括号分组时的结果相同:

-gt

或者,您可以使用shell arithmetic并利用布尔结果表示为if [[ ((9 -gt 220)) ]]; then echo "here"; fi "0"的事实:

"1"

if [[ $((9 > 200)) == 1 ]]; then echo "here"; fi 复合命令

在第二个示例中,您正在使用(( expression ))命令:

(( expression ))

根据LINK的规则评估if ((9 > 220)); then echo "here"; fi expression说:

  

man bash

     

根据ARITHMETIC EVALUATION下面描述的规则评估表达式。如果表达式的值不为零,则返回状态为0;否则返回状态为1.这完全相同   到((expression))

答案 2 :(得分:0)

[[ ]]内部,括号不会触发算术上下文,它们仅被解释为分组/优先级 1 。所有这些都是等价的:

$ [[ 0 < 1 ]] && echo yes
yes
$ [[ (0 < 1) ]] && echo yes
yes
$ [[ ((0 < 1)) ]] && echo yes
yes
$ [[ (((0 < 1))) ]] && echo yes
yes
$ [[ ((((0 < 1)))) ]] && echo yes
yes

如果我们有不平衡的括号,Bash会抱怨:

$ [[ ((((0 < 1))) ]] && echo yes
bash: unexpected token `]]', expected `)'
bash: syntax error near `]]'

尽管如此,<中的>[[ ]]用于词典字符串比较,因此上述语句只检查01之前按字典顺序排序。

观察:

$ [[ 11 < 2 ]] && echo yes
yes

要比较数字,您必须使用-gt-lt-ge-leeqne而不是{{ 1}},><>=<==

!=

由于您已经在使用$ [[ 11 -lt 2 ]] && echo yes || echo no no ,因此您可以使用它来比较数字:

(( ))

在我看来,这是最简单,最清晰的方法,如果你知道你有Bash可以使用。

1 请参阅the manual about [[ ]]

  

可以使用以下列出的运算符组合表达式   降序优先顺序:

     

$ (( 11 < 2 )) && echo yes || echo no no
  返回 ( expression ) 的值。这可以用来覆盖运算符的正常优先级。

向Glenn Jackman提示他在另一个答案的评论中指出手册。

答案 3 :(得分:-1)

双括号是算术上下文。如果您使用括号,则必须使用-lt小于和-gt小于。Series。请参阅Comparing numbers in Bash