是的,我们有两种不同的方法来比较两个整数。

是的,我们有两种不同的方法来比较两个整数。

在 Bash 中,可以使用条件表达式比较两个整数

精氨酸1OP精氨酸2

-eqOP 是、-ne-lt-le-gt或之一-ge。这些算术二元运算符返回 true,如果精氨酸1等于、不等于、小于、小于或等于、大于或大于或等于精氨酸2, 分别。精氨酸1精氨酸2可以是正整数或负整数。

或算术表达式:

<= >= < >比较

== !=平等与不平等

为什么我们有两种不同的方法来比较两个整数?什么时候用哪个?

例如,[[ 3 -lt 2 ]]使用条件表达式、(( 3 < 2 ))使用算术表达式。当比较为真时两者都返回 0

比较两个整数时,这两种方法可以互换使用吗?如果是,为什么 Bash 有两种方法而不是一种?

答案1

是的,我们有两种不同的方法来比较两个整数。

看来这些事实在这个论坛上并没有被广泛接受:

  1. 在该惯用语中,用于[ ]算术比较的运算符是-eq-ne-lt-le和。-gt-ge

    因为它们也在测试命令和[[ ]].

    是的,在这个习语中,=<等是字符串运算符。

  2. 在该惯用语中,(( ))用于算术比较的运算符是==, !=, <, <=, >, 和>=

    不,这不是“算术扩展”(以 开头$)作为$(( ))。它在 man bash 中被定义为“复合命令”。

    是的,它遵循“算术扩展”的相同规则(内部),但没有输出,只有退出值。它可以这样使用:

if (( 2 > 1 )); then ...

为什么我们有两种不同的方法来比较两个整数?

我猜想后者(( ))是作为一种更简单的执行算术测试的方法而开发的。它几乎与 相同,$(( ))但没有输出。

为什么是两个?这与为什么我们有两个printf(外部和内置)或四个测试(外部test、内置和test)相同。这就是贝壳生长的方式,一年内改善某些区域,第二年改善其他一些区域。[[[

什么时候用哪个?

这是一个非常棘手的问题,因为不应该有任何有效的差异。当然,a 的[ ]工作方式和 a 的内部工作方式存在一些差异(( )),但是:比较两个整数哪个更好?任何人!。

比较两个整数时,这两种方法可以互换使用吗?

对于两个数字我不得不说是。
但对于变量、展开式、数学运算,可能存在关键差异,应该有利于其中之一。我不能说两者绝对相等。其一,(( ))可以按顺序执行多个数学运算:

if (( a=1, b=2, c=a+b*b )); then echo "$c"; fi

如果是,为什么 Bash 有两种方法而不是一种?

如果两者都有帮助,为什么不呢?

答案2

从历史上看,该test命令首先存在(至少可以追溯到Unix第七版1979 年)。它使用运算符=and!=来比较字符串,and -eq-ne-lt等来比较数字。例如,test 0 = 00是假的,但是test 0 -eq 00是真的。我不知道为什么选择这种语法,但可能是为了避免使用<and >,shell 会将其解析为重定向运算符。test几年后,该命令得到了另一种语法:[ … ]相当于test ….

条件语法[[ … ]](其中<and>可以用作不带引号的运算符)是后来在 ksh 中添加的。它与 保持向后兼容性[ … ],因此它使用相同的运算符,但添加了<>来比较字符串(例如,[[ 9 > 10 ]]but [[ 9 -lt 10 ]])。有关更多信息,请参阅使用单括号或双括号 - bash

算术表达式也晚于test命令出现,在 Korn shell 中,在 20 世纪 80 年代的某个时候。它们遵循在 Unix 圈子里非常流行的 C 语言的语法。因此他们使用了 C 的运算符:==相等、<=小于或等于等。

Unix 第七版没有算术表达式,但它有expr命令,它还实现了类似 C 的整数运算语法,包括其比较运算符。在 shell 脚本中,字符<>必须被引用以保护它们免受 shell 的影响,例如if expr 1 \< 2; …相当于if test 1 -lt 2; …。向 shell 中添加算术表达式使得大多数用法都过时了expr,因此今天它并不为人所知。

在 sh 脚本中,您通常使用算术表达式来计算整数值并[ … ]比较整数。

if [ "$((x + y))" -lt "$z" ]; then …

在 ksh、bash 或 zsh 脚本中,您可以同时使用((…))两者。

if ((x + y < z)); then …

[[ … ]]如果您想使用涉及整数以外的内容的条件,则该形式非常有用。

答案3

根据测试手册页,= 和 != 用于字符串比较,而表达式 -eq、-gt、-lt、-ge、-le 和 -ne 是整数比较。我在编写 shell 脚本时一直遵循这个约定,而且它总是有效的。请注意,如果表达式中有变量,则可能需要以某种方式引用变量以避免进行空比较。

在纸面上,我们不假思索地进行字符串/数字比较。另一方面,计算机不知道 987 是数字还是字符串。您需要不同的操作员告诉计算机该做什么,以便获得正确的结果。有一些附加信息这里这解释了一些历史。本质上,这些变量是无类型的,并且为了历史兼容性而保持这种状态。

相关内容