壳比较中的单等号和双等号(=)有什么区别?


28

阅读该说明以比较内部的字符串,if我们需要使用双方括号。有些书说比较可以用=。但这也适用==

#!/bin/bash
a="hello"
b="world"
if [[ $a == $b ]];then
    echo "equal"
fi

===比较之间有区别吗?


4
这里某处有问题吗?如果是这样,我看不到。=是为[==是为[[
克里斯·

@ChrisDown绝对不正确。
xdavidliu

@xdavidliu需要详细说明吗?根据POSIX的理解,这确实正确的,因为POSIX并不了解==,这就是为什么您应该将=(与等式使用)[==(将模式匹配,并将其与具有引号意识的语义一起)与[[。见help testVS help [[
克里斯·

@ChrisDown也许我误解了“是为”的含义。如果“是”表示“仅适用于”,则注释不正确,因为[ foo == foo ] && echo foo肯定会打印出来foo,表明该方法==适用于[。但是,如果用“是”来表示“打算与”使用,那么我有较少的异议。
xdavidliu

在您提到的特定情况下,@ xdavidliu是“用于”的意思是“由POSIX定义”。仅仅因为bash会接受它的方便性,并不意味着它是推荐的-如果您仍然避开可移植性,请[[首先使用对记号化,单词拆分等有了更细微差别的理解的第一位
克里斯·唐恩

Answers:


28

[[ $a == $b ]]不是比较,而是模式匹配。您需要[[ $a == "$b" ]]进行字节对字节的相等比较。===任何[[...]]受支持的shell 相同(由引​​入ksh)。

[[...]]不是标准sh语法。的[ 命令是标准的,并且标准的比较操作符有=(尽管一些[实施方式中也认识==)。

就像在任何命令的任何参数中一样,变量必须加引号,因此:

[ "$a" = "$b" ]

在标准情况下sh,模式匹配通过以下方式完成case

case $a in
  ($b) ...
esac

为了完整起见,您可能会在Shell脚本中遇到其他类似相等的运算符:

  • [ "$a" -eq "$b" ][比较十进制整数的标准运算符。有些[实现允许数字周围有空格,有些实现允许任意算术表达式,但这是不可移植的。可移植的是,可以使用[ "$((a))" -eq "$((b))" ]它。另请参见[ "$((a == b))" -ne 0 ]以下内容的标准等效项(除了POSIXly,仅当行为$a并且$b包含整数常量时才指定行为):
  • ((a == b)),来自ksh并在zsh和中找到,bash如果存储在中的算术表达式的求值与$a的相同,则返回true $b。通常,它用于比较数字。请注意,shell之间在如何计算算术表达式以及支持哪种数字方面有所不同(例如bash和ksh的某些实现/版本不支持浮点运算,也不将前导零视为八进制数字)。

  • expr "$a" = "$b"如果两个操作数都被识别为十进制整数(某些数字允许空格),则进行数字比较,否则检查两个字符串运算符是否具有相同的排序顺序。这也将失败的值$a或者$bexpr运营商喜欢(substr...

  • awk 'BEGIN{exit !(ARGV[1] == ARGV[2])}' "$a" "$b":如果$a$b被识别为数字(至少十进制整数和浮点数,例如1.2,-1.5e-4,忽略了前导尾随空格,有些还识别十六进制,八进制或由识别的任何东西strtod()),则将执行数字比较。否则,取决于实现方式,它要么是字节到字节的字符串比较,要么就像是expr进行strcoll()比较,即是否$a$b排序相同。

也可以看看:


13

这些在bash中是等效的:

[[ $x == "$y" ]]
[[ $x = "$y" ]]
[ "$x" == "$y" ]
[ "$x" = "$y" ]

前两个$ x变量不必加引号。Bash在[内而不是在[[内:

$ x='a b'
$ [ -s $x ]
-bash: [: a: binary operator expected
$ [[ -s $x ]]
$ ls
$ [ a = * ]
-bash: [: a: unary operator expected
$ [[ a = * ]]
$ 

[[ $x = "$y" ]]是一个字符串比较,但是[[ $x = $y ]]一个模式匹配表达式:

$ y='a*'; [[ aa = "$y" ]]; echo $?
1
$ y='a*'; [[ aa = $y ]]; echo $?
0

-eq仅用于整数:

$ [[ x.x -eq x.x ]]
-bash: [[: x.x: syntax error: invalid arithmetic operator (error token is ".x")
$ x=9; [[ "x" -eq 9 ]]; echo $?
0

另请参阅BashFAQ / 031:test和[和[[有什么区别?

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.