重击:双等于vs -eq


47

我正在bash中进行整数比较(试图查看用户是否以root用户身份运行),并且发现了两种不同的实现方式:

双重等于:

if [ $UID == 0 ]
then
fi

-eq

if [ $UID -eq 0 ]
then
fi

我知道bash中没有> =或<=,只有-ge和-le,所以为什么==会有一个-eq

双方比较的方式是否有所不同?


3
请注意,方括号内必须有空格:[ $UID -eq 0 ],而不是[ $UID -eq 0]
吉尔(Gilles)'所以

Answers:


50

==是的bash特定别名=,它执行字符串(词法)比较而不是-eq数字比较。(这是从Perl倒过来的:单词样式运算符是数字,符号运算符是词法。)


这是否意味着如果双方都是整数,它将双方都转换为字符串,然后将它们进行比较?
Beatgammit

5
更准确地说是相反的:所有东西都是一个字符串,-eq告诉bash将字符串解释为整数(0如果字符串不是数字,则在没有警告的情况下生成)。
geekosaur 2011年

11
@tjameson举个例子:[ 01 -eq 1 ]但是[ 01 != 1 ]
吉尔(Gilles)'所以

3
请注意,虽然==作为[运算符是非标准的,不应使用,但它不是bash特定的。它由ksh引入,并由zsh(尽管首先=需要引用),yash和GNU [实用程序(以及在某些系统上至少以ksh脚本实现的任何此类实用程序)支持。
斯特凡Chazelas

@geekosaur如果我的字符串不是数字,我会从bash v4.3.42得到警告:$ if [ "hello" -eq 0 ]; then echo true; fi bash:[:你好:预期为整数表达式
Andrew Bainbridge

13

详细阐述bollovan的答案 ...

字符串没有>=<=比较运算符。但是您可以将它们与((...))算术命令一起使用以比较整数。

您还可以使用其他字符串比较操作符(==!=<>,但没有=),如果你里面用它们来比较整数((...))

例子

  • 两者[[ 01 -eq 1 ]](( 01 == 1 ))都进行整数比较。两者都是对的。
  • 两者[[ 01 == 1 ]][ 01 = 1 ]都进行字符串比较。两者都是错误的。
  • 双方(( 01 -eq 1 ))(( 01 = 1 ))会返回一个错误。

注意:并非所有外壳程序都支持[[...]]双括号语法和双括号语法((...))


1
请注意(mksh/ zsh除外(在POSIX模式下除外(尽管不是POSIX功能)))(( 010 == 10 ))将返回false,因为010它将被视为八进制数字(十进制为8)。
斯特凡Chazelas

请注意,虽然大多数test/ [实现没有>=/ <=运营商(yash[具有虽然),expr有这样的运营商,但如果参数被识别为数字会做算术比较(expr 01 '>=' 1返回true,expr X01 '>=' X1返回false)。
斯特凡Chazelas

7

如果要进行整数比较,最好使用(()),也可以使用> =等。

例:

if (( $UID == 0 )); then
   echo "You are root"
else
   echo "You are not root"
fi

(( UID == 0 ))(( ! UID ))对此很重要。请注意,这((...))是非标准的(此ksh功能也受变体支持bashzsh带有变体)。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.