【问题标题】:Why does bash evaluate comparison of numbers lexicographically not numerically?为什么 bash 按字典顺序而不是数字方式评估数字的比较?
【发布时间】:2020-03-10 04:29:25
【问题描述】:

有人可以解释 bash 的“if”块的以下行为吗?

我使用以下简单代码检查 first_value 是否小于 second_value

first_value=67
second_value=2

if [[  "${first_value}" < "${second_value}" ]];
then 
    echo "Yes"
else 
    echo "No"
fi

问题是

如果 second_value 是 1,2,3,4,5,6,10,11,... 块将返回“No”

但如果 second_value 为 7、8、9,则该块将返回“Yes”(必须为“No”)

解决方法是使用“-lt”而不是“”,但我想了解“if”的这种行为堵塞。

bash 版本是“GNU bash,版本 4.2.46(2)-release (x86_64-redhat-linux-gnu)”

操作系统是“CentOS Linux release 7.5.1804 (Core)”

【问题讨论】:

  • @Inian :这个问题不是重复的。 “重复”链接指向有关如何实现数值比较的讨论,但 OP 表示他至少知道如何正确执行此操作的一种可能性。相反,他想知道为什么他的错误方法导致了他观察到的行为。
  • @Inian:谢谢。我已删除我的评论并创建了一个答案。
  • 嗨,维克,我的回答解决了你的问题吗? What should I do when someone answers my question
  • 这与if 块无关;这与[[ ... ]] 命令有关,它不是 部分if 块的语法。
  • bash 可以直接从提示符处提供文档:输入help [[ 然后help test

标签: bash if-statement syntax


【解决方案1】:

这种行为的原因是[[ "${first_value}" &lt; "${second_value}" ]] 实际上是字典比较,因为[[ exp ]] 括号。

正如问题中提到的 OP,可能的解决方法是使用 -lt 运算符。

在 bash 中,您可以使用算术上下文:

if (( $first_value < $second_value ));
then 
    echo "Yes"
else 
    echo "No"
fi

甚至更简单

if (( first_value < second_value ));
then 
    echo "Yes"
else 
    echo "No"
fi

【讨论】:

  • 实际上,在(( ... )) 内不需要显式取消引用变量,因此该语句可以写为if (( first_value &lt; second_value )),我认为它(小)更具可读性。
【解决方案2】:

至于您的问题:首先, if 块不返回任何内容。它只执行一组语句或另一组语句,在您的情况下将某些内容写入标准输出。

现在解释您观察到的行为。

[[ ... ]] 表达式中的

[[ 67 < 7 ]]

“67”在词法上小于“7”,因此 [[ .... ]] 返回状态码 0,这意味着 if 正在执行 then 部分,这会导致打印 Yes。

【讨论】:

    猜你喜欢
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 2023-03-29
    • 1970-01-01
    相关资源
    最近更新 更多