在 Bash 中,可以使用条件表达式比较两个整数
精氨酸1OP精氨酸2
-eq
OP 是、-ne
、-lt
、-le
、-gt
或之一-ge
。这些算术二元运算符返回 true,如果精氨酸1等于、不等于、小于、小于或等于、大于或大于或等于精氨酸2, 分别。精氨酸1和精氨酸2可以是正整数或负整数。
或算术表达式:
<= >= < >
比较
== !=
平等与不平等
为什么我们有两种不同的方法来比较两个整数?什么时候用哪个?
例如,[[ 3 -lt 2 ]]
使用条件表达式、(( 3 < 2 ))
使用算术表达式。当比较为真时两者都返回 0
比较两个整数时,这两种方法可以互换使用吗?如果是,为什么 Bash 有两种方法而不是一种?
答案1
是的,我们有两种不同的方法来比较两个整数。
看来这些事实在这个论坛上并没有被广泛接受:
在该惯用语中,用于
[ ]
算术比较的运算符是-eq
、-ne
、-lt
、-le
和。-gt
-ge
因为它们也在测试命令和
[[ ]]
.是的,在这个习语中,
=
、<
等是字符串运算符。在该惯用语中,
(( ))
用于算术比较的运算符是==
,!=
,<
,<=
,>
, 和>=
。不,这不是“算术扩展”(以 开头
$
)作为$(( ))
。它在 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 是数字还是字符串。您需要不同的操作员告诉计算机该做什么,以便获得正确的结果。有一些附加信息这里这解释了一些历史。本质上,这些变量是无类型的,并且为了历史兼容性而保持这种状态。