Bash 相等运算符 ( == , -eq )

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20449543/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:30:16  来源:igfitidea点击:

Bash Equality Operators ( == , -eq )

bash

提问by Victor Brunell

Can someone please explain the difference between -eqand ==in bash scripting?

有人可以解释一下bash 脚本-eq==bash 脚本之间的区别吗?

Is there any difference between the following?

以下有什么区别吗?

[ $a -eq $b ]and [ $a == $b ]

[ $a -eq $b ][ $a == $b ]

Is it simply that ==is only used when the variables contain numbers?

仅仅==是在变量包含数字时才使用吗?

回答by John Kugelman

It's the other way around: =and ==are for string comparisons, -eqis for numeric ones. -eqis in the same family as -lt, -le, -gt, -ge, and -ne, if that helps you remember which is which.

这是周围的其他方法:===用于字符串比较,-eq是数字的。-eq在同一家庭-lt-le-gt-ge,和-ne,如果这能帮助你记住哪个是哪个。

==is a bash-ism, by the way. It's better to use the POSIX =. In bash the two are equivalent, and in plain sh =is the only one guaranteed to work.

==顺便说一句,这是一种bash-ism。最好使用 POSIX =。在 bash 中,这两者是等价的,而在普通的 sh 中,=是唯一保证可以工作的。

$ a=foo
$ [ "$a" = foo ]; echo "$?"       # POSIX sh
0
$ [ "$a" == foo ]; echo "$?"      # bash specific
0
$ [ "$a" -eq foo ]; echo "$?"     # wrong
-bash: [: foo: integer expression expected
2

(Side note: Quote those variable expansions! Do not leave out the double quotes above.)

(旁注:引用那些变量扩展!不要遗漏上面的双引号。)

If you're writing a #!/bin/bashscript then I recommend using [[instead. The doubled form has more features, more natural syntax, and fewer gotchas that will trip you up. Double quotes are no longer required around $a, for one:

如果你正在写一个#!/bin/bash剧本,然后我建议使用[[代替。双重形式具有更多功能、更自然的语法和更少的陷阱。周围不再需要双引号$a,例如:

$ [[ $a == foo ]]; echo "$?"      # bash specific
0

See also:

也可以看看:

回答by dawg

It depends on the Test Constructaround the operator. Your options are double parenthesis, double braces, single braces, or test

这取决于操作员周围的测试构造。您的选项是双括号、双大括号、单大括号或测试

If you use ((...)), you are testing arithmetic equity with ==as in C:

如果您使用((...)),则您正在使用==C 中的方式测试算术公平性:

$ (( 1==1 )); echo $?
0
$ (( 1==2 )); echo $?
1

(Note: 0means truein the Unix sense and non zero is a failed test)

(注:0手段true在Unix意识和非零是一个失败的试验)

Using -eqinside of double parenthesis is a syntax error.

使用-eq双括号里面是一个语法错误。

If you are using [...](or single brace) or [[...]](or double brace), or testyou can use one of -eq, -ne, -lt, -le, -gt, or -ge as an arithmetic comparison.

如果您使用[...](或单括号)或[[...]](或双括号),或者test您可以使用 -eq、-ne、-lt、-le、-gt 或-ge 作为算术比较

$ [ 1 -eq 1 ]; echo $?
0
$ [ 1 -eq 2 ]; echo $?
1
$ test 1 -eq 1; echo $?
0

The ==inside of single or double braces (or testcommand) is one of the string comparison operators:

==单或双括号(或内部test命令)是一个字符串比较操作符

$ [[ "abc" == "abc" ]]; echo $?
0
$ [[ "abc" == "ABC" ]]; echo $?
1

As a string operator, =is equivalent to ==and note the whitespace around =or ==its required.

作为字符串运算符,=相当于==并注意周围的空格=或其==必需的。

While you cando [[ 1 == 1 ]]or [[ $(( 1+1 )) == 2 ]]it is testing the string equality -- not the arithmetic equality.

虽然你可以[[ 1 == 1 ]]或者[[ $(( 1+1 )) == 2 ]]它正在测试字符串相等性——而不是算术相等性。

So -eqproduces the result probablyexpected that the integer value of 1+1is equal to 2even though the RH is a string and has a trailing space:

所以-eq产生的结果可能是预期的整数值1+1等于2RH 是一个字符串并且有一个尾随空格:

$ [[ $(( 1+1 )) -eq  "2 " ]]; echo $?
0

While a string comparison of the same picks up the trailing space and therefor the string comparison fails:

虽然相同的字符串比较会拾取尾随空格,因此字符串比较失败:

$ [[ $(( 1+1 )) ==  "2 " ]]; echo $?
1

And a mistaken string comparison can produce the complete wrong answer. '10' is lexicographicallyless than '2', so a string comparison returns trueor 0. So many are bitten by this bug:

错误的字符串比较会产生完全错误的答案。'10' 按字典顺序小于 '2',因此字符串比较返回trueor 0。这么多人被这个错误咬了:

$ [[ 10 < 2 ]]; echo $?
0

vs the correct test for 10 being arithmeticallyless than 2:

与 10 在算术上小于 2的正确测试相比:

$ [[ 10 -lt 2 ]]; echo $?
1


In comments, there is a question of the technicalreason using the integer -eqon strings returns True for strings that are not the same:

在评论中,有一个技术原因问题,-eq在字符串上使用整数返回 True 对于不相同的字符串:

$ [[ "yes" -eq "no" ]]; echo $?
0

The reason is that Bash is untyped. The -eqcauses the strings to be interpreted as integers if possibleincluding base conversion:

原因是 Bash 是无类型的如果可能的话-eq会导致字符串被解释为整数包括基数转换:

$ [[ "0x10" -eq 16 ]]; echo $?
0
$ [[ "010" -eq 8 ]]; echo $?
0
$ [[ "100" -eq 100 ]]; echo $?
0

And 0if Bash thinks it is just a string:

0如果猛砸认为它只是一个字符串:

$ [[ "yes" -eq 0 ]]; echo $?
0
$ [[ "yes" -eq 1 ]]; echo $?
1

So [[ "yes" -eq "no" ]]is equivalent to [[ 0 -eq 0 ]]

所以[[ "yes" -eq "no" ]]相当于[[ 0 -eq 0 ]]

Last note: Many of the Bash specific extensions to the Test Constructs are not POSIX and therefore will fail in other shells. Other shells generally do not support [[...]]and ((...))or ==.

最后一点:测试构造的许多 Bash 特定扩展不是 POSIX,因此在其他 shell 中会失败。其他外壳一般不支持[[...]]and((...))==

回答by Elliott Frisch

==is a bash-specific alias for =and it performs a string (lexical) comparison instead of a numeric comparison. eqbeing a numeric comparison of course.

==是 bash 特定的别名=,它执行字符串(词法)比较而不是数字比较。eq当然是数字比较。

Finally, I usually prefer to use the form if [ "$a" == "$b" ]

最后,我通常更喜欢使用表单 if [ "$a" == "$b" ]

回答by bk-se

Guys: Several answers show dangerous examples. OP's example [ $a == $b ]specifically used unquoted variable substitution (as of Oct '17 edit). For [...]that is safe for string equality.

伙计们:几个答案显示了危险的例子。OP 的示例[ $a == $b ]专门使用了未加引号的变量替换(截至 17 年 10 月编辑)。因为[...]这对于字符串相等是安全的。

But if you're going to enumerate alternatives like [[...]], you must inform also that the right-hand-side must be quoted. If not quoted, it is a pattern match! (From bash man page: "Any part of the pattern may be quoted to force it to be matched as a string.").

但是,如果您要枚举类似 的替代方案[[...]],您还必须通知右侧必须被引用。如果没有引用,就是模式匹配!(来自 bash 手册页:“可以引用模式的任何部分以强制将其作为字符串进行匹配。”​​)。

Here in bash, the two statements yielding "yes" are pattern matching, other three are string equality:

在 bash 中,产生“yes”的两个语句是模式匹配,其他三个是字符串相等:

$ rht="A*"
$ lft="AB"
$ [ $lft = $rht ] && echo yes
$ [ $lft == $rht ] && echo yes
$ [[ $lft = $rht ]] && echo yes
yes
$ [[ $lft == $rht ]] && echo yes
yes
$ [[ $lft == "$rht" ]] && echo yes
$