【问题标题】:Why do the following string comparisons return different results?为什么以下字符串比较会返回不同的结果?
【发布时间】:2019-12-21 13:48:33
【问题描述】:

以下命令有什么区别,为什么输出不一样?:

echo $[ "a" == "a" ]

1
 
echo $(( "a" == "a" ))

1

[ "a" == "a" ]; echo $?;

0

【问题讨论】:

  • echo $[ "a" == "a" ] 导致"bash: "a" == "a" : syntax error: operand expected (error token is ""a" == "a" ")"

标签: bash relational-operators


【解决方案1】:

对我来说,这些操作看起来是相同的,但前两个附加了 $ return false...

这是不正确的。前两个表达式是算术表达式。它们产生一个数字结果。在许多语言中很常见,布尔 True 计算为整数值 1,而 False 计算为 0

请注意,$[...]$((...)) 是等价的,但前者的 is deprecated 不再记录。

...而第三个返回 true

这也不是真的。在这里,您正在查看命令的返回码,而不是像前两个示例中那样打印出表达式的值。命令不返回布尔信息;它们返回一个整数,指示它们是否成功(返回码为 0)或不成功(任何非零返回码)。


关于您的问题,false 命令不会返回“false”;如果您阅读手册页,它会说:

false - 什么都不做,不成功

也就是说,它是一个不执行任何操作并返回错误代码(即非零退出代码,在本例中为 1)的命令。当然,true 类似,只是它返回一个成功的退出代码(即0)。

【讨论】:

  • 如果您对此答案有疑问,我很抱歉。如果您觉得它没有充分解决您的问题,欢迎您接受另一个问题。不过,我很确定我是对的。
【解决方案2】:
echo $[ "a" == "a" ]

使用已弃用的整数扩展语法,已被 $(( ... )) 取代。

echo $(( "a" == "a" ))

使用所谓的算术扩展:在$(( ... )) 中,您可以在返回值之前计算逻辑和数字表达式。

[ "a" == "a" ]; echo $?

以标准 bash 方式进行逻辑测试:当程序成功执行时,程序的返回码为 0,否则为非零。 [ 实际上是名为test 的程序的另一个名称,当它测试的表达式为真时返回成功(即0)。

不在您的列表中,但相关:

(( "a" == "a" )); echo $?

0

这会进行算术扩展,如果结果为真则返回成功 (0),而不是生成表达式本身的值。

[[ "a" == "a" ]]; echo $?

0

[[ ... ]] 是 bash 语法,用于直接进行条件测试,而不是调用程序 test

一些示例用法

您将使用$(( ... )) 来初始化变量或回显输出,就像您所做的那样:

foo=$(( 1 + 4))
echo $(( 5 + 7 ))

您可以在条件语句中使用[ ... ](( ... ))[[ ... ]]

if [[ $a == bar ]]; then
   echo $a is bar
fi

i=0
while (( i < 10 )); do
   echo i=$i
   i=$(( i + 1 ))
done

【讨论】:

    【解决方案3】:

    您的前两个执行算术比较(永远不要使用 $[...];它没有记录,已过时,并被 $((...))(字面意思是几十年前)取代)。在算术上下文中,字符串被视为隐式参数扩展,递归地,直到产生一个整数。未定义的参数被视为 0。如果比较结果为真,则结果表达式的值为 1,如果为假,则值为 0。比较:

    $ echo $(( a == b ))  # Compares 0 == 0
    1
    $ a=5; b=7
    $ echo $(( a == b ))  # Compares 5 == 7
    0
    

    最后一个按预期执行字符串比较。 [ ... ]的退出状态,比较为真时为0,为假时为1。 (这是布尔表达式的 value 与计算布尔表达式的 command 的结果之间的差异。)使用 -eq 运算符进行整数比较.

    $ [ a = a ]; echo $?  # String comparison of the letter a to itself
    0
    $ [ a = b ]; echo $?  # String comparison of the letter a to the letter b
    1
    $ unset a b
    $ [ a -eq b ]; echo $?  # Again, 0 -eq 0
    0
    $ a=5; b=7
    $ [ "$a" -eq "$b" ]; echo $?  # Again, 5 -eq 7
    1
    

    【讨论】:

      猜你喜欢
      • 2015-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 2010-12-03
      相关资源
      最近更新 更多