什么"-ne"在bash中意味着什么?

Zen*_*nce 48 syntax bash shell

命令"-ne"在bash脚本中的含义是什么?

例如,bash脚本中的以下行是做什么的?

[ $RESULT -ne 0 ] 
Run Code Online (Sandbox Code Playgroud)

Kei*_*son 72

如果您还不知道在哪里查找,这是难以搜索的内容之一.

[实际上是一个命令,而不是你所期望的bash shell语法的一部分.它恰好是Bash内置命令,因此它在Bash手册中有记录.

还有一个外部命令可以做同样的事情; 在许多系统上,它由GNU Coreutils包提供.

[等同于test命令,除了[需要]作为其最后一个参数,而test不是.

假设您的系统上安装了bash文档,则键入info bash并搜索

__PRE__

(反引号和撇号是搜索的一部分),您将找到'test'命令的文档,也称为'['命令.

在引用"Bash条件表达式"之后,将引导您描述[,即数字不等式运算符("ne"代表"不相等".相反,test字符串不等式运算符.

您还可以在网上找到bash文档.

该命令的官方定义-ne是POSIX标准(bash实现应该合理地符合,可能有一些扩展).


Ome*_*man 37

"不相等"所以在这种情况下,$RESULT测试不等于零.

但是,测试是按数字进行的,而不是按字母顺序进行的:

n1 -ne n2     True if the integers n1 and n2 are not algebraically equal.
Run Code Online (Sandbox Code Playgroud)

相比:

s1 != s2      True if the strings s1 and s2 are not identical.
Run Code Online (Sandbox Code Playgroud)

  • 指出数字和字符串比较之间的区别的好点......这很容易被忽视 (2认同)

MrP*_*ead 5

为之前的答案添加额外的上下文。

自从我十几年前开始使用 BaSH 编程以来,我仍然发现数学运算符的主题很难记住。由于 BaSH 有许多怪癖,因此在其中进行编程常常令人沮丧。一个典型的例子是对包含整数的变量进行相等/不相等比较的编码,因为与其他基本操作数(例如小于、大于等)相比,它需要完全不同的技术。处理这些其他操作数(例如 )的一些典型方法((..))在应用于等于/不等于公式时无法正常工作。

根据OP的问题,让我们看一些示例,了解如何尝试在 BaSH 中编写两个整数之间的数字比较,以及哪些方法有效或无效,使用示例来帮助阐明该做和不该做。 ts。我将把我的评论限制在相等/不相等的逻辑上。

如果不提及基数系统,就无法对这一主题进行彻底的讨论。BaSH 文档通常清晰如泥。例如,在某些情况下,BaSH 假定整数是八进制(8 基),而大多数人假定十进制(10 基)。在使用数字比较编写脚本时,很容易没有意识到您正在创建问题,直到您在将来某个时候由于意外结果而调试它。虽然 BaSH 的行为有时显得不一致,但事实上,这只是完全理解 BaSH 如何解释字符串和数字的问题。

比较不带前导零的整数。

当您确定要比较的整数永远不会有前导零时,您可以使用以下任何方法:

#/bin/bash
a=4
b=4
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"
Run Code Online (Sandbox Code Playgroud)

比较整数前导零。

现在,假设您将或可能有至少一个带有前导零的变量。如果是这种情况,那么某些方法将无法正常工作(将生成错误或返回错误结果)。发生这种情况的原因要么是 BaSH 将数值解释为字符串并将两个数字作为字符串进行比较,要么是因为 BaSH 期望这些值是 8 基整数,但遇到了在八进制系统下无法解释的字符。

解决这些问题的方法有很多种,但最简单的方法就是不使用某些技术来比较整数。


当您尝试比较实际值时,这些方法不起作用。他们将错误地返回“不等于”结果。当然,如果您确实希望比较文字字符串,那么这可能是一个理想的结果,因此这实际上取决于您的用例。不管怎样,重点是这些公式将把“x”和“0x”视为不相等,即使对于人类来说它们是相同的数值。

看一些例子:

整数,无前导零。这些公式中的任何一个都可以。

#!/bin/bash
a=7
b=7
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"

Output:
method 1: equal
method 2: equal
method 3: equal
method 4: equal
method 5: equal
Run Code Online (Sandbox Code Playgroud)

同样在这里; 看起来不错(但事实并非如此):

#!/bin/bash
a=7
b=8
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"

Output:
method 1: not equal
method 2: not equal
method 3: not equal
method 4: not equal
method 5: not equal
Run Code Online (Sandbox Code Playgroud)

当引入前导零时就会出现问题。

#!/bin/bash
a=04
b=4
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"

Output:
method 1: not equal
method 2: not equal
method 3: equal
method 4: equal
method 5: equal
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的示例中,输出结果不一致。这是因为前两个方法将 $a 与 $b 作为字符串进行比较,这意味着它们的内容是按字面比较的。同时,第三到第五种方法将 $a 和 $b 转换为数字,然后比较它们,所以这些方法似乎可以正常工作。然而,还有另一个有问题的场景值得一提。

一般应避免第五种方法。

#!/bin/bash
a=8
b=08
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"

Output:
method 1: not equal
method 2: not equal
method 3: equal
method 4: equal
method 5: main.sh: line 8: ((: 08: value too great for base (error token is "08")
equal
Run Code Online (Sandbox Code Playgroud)

正如您在上面看到的,前两个方法返回 FALSE(不等于)比较结果,因为它们将两个值作为字符串进行比较。更重要的是,第五种方法会产生错误,因为 BaSH 需要八进制数字,并且不知道如何处理以零开头的非零值。此方法的另一个挑战是,即使您要抑制错误消息,它每次都会返回 FALSE 结果,无论这是否是正确的结果,如下所示。

#!/bin/bash
a=8
b=09
printf "method 1: "; if [ $a != $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 2: "; if [ "$a" != "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 5: "; if (( a != b )); then printf "not equal"; else printf "equal"; fi; printf "\n"

Output:
method 1: not equal
method 2: not equal
method 3: not equal
method 4: not equal
method 5: main.sh: line 8: ((: 09: value too great for base (error token is "09")
equal
Run Code Online (Sandbox Code Playgroud)

还值得一提的是,第五种方法的这种变体也效果不佳:

printf "method 5: "; if (( $a != $b )); then printf "not equal"; else printf "equal"; fi; printf "\n"
Run Code Online (Sandbox Code Playgroud)

这也不是:

printf "method 5: "; if (( "$a" != "$b" )); then printf "not equal"; else printf "equal"; fi; printf "\n"
Run Code Online (Sandbox Code Playgroud)

底线

最重要的是,在 BaSH 中比较两个整数时,通常应该使用这些类型的公式表达式,而不是提到的其他类型。这假设您的用例涉及使用等于或不等于运算符来比较两个 10 基整数。

printf "method 3: "; if [ $a -ne $b ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -ne "$b" ]; then printf "not equal"; else printf "equal"; fi; printf "\n"
Run Code Online (Sandbox Code Playgroud)

比较整数是否相等时,同样的逻辑也是如此。

printf "method 3: "; if [ $a -eq $b ]; then printf "equal"; else printf "not equal"; fi; printf "\n"
printf "method 4: "; if [ "$a" -eq "$b" ]; then printf "equal"; else printf "not equal"; fi; printf "\n"
Run Code Online (Sandbox Code Playgroud)