use*_*539 52 bash shell-script
为了比较里面的字符串,if
我们需要使用双方括号。有些书说比较可以通过=
. 但它也适用于==
。
#!/bin/bash
a="hello"
b="world"
if [[ $a == $b ]];then
echo "equal"
fi
Run Code Online (Sandbox Code Playgroud)
比较=
和==
比较有区别吗?
Sté*_*las 54
[[ $a == $b ]]
不是比较,而是模式匹配。您需要[[ $a == "$b" ]]
进行字节到字节的相等比较。=
与==
任何支持[[...]]
(由 引入ksh
)的shell相同。
[[...]]
不是标准sh
语法。的[
命令是标准的,并且标准的比较操作符有=
(尽管一些[
实施方式中还认识==
¹)。
就像在任何命令的任何参数中一样,必须引用变量扩展以防止split+glob和空删除(仅后者在 中执行zsh
),因此:
[ "$a" = "$b" ]
Run Code Online (Sandbox Code Playgroud)
在标准中sh
,模式匹配是通过以下方式完成的case
:
case $a in
($b) ...
esac
Run Code Online (Sandbox Code Playgroud)
为了完整起见,您可能会在 shell 脚本中遇到其他类似等式的运算符:
[ "$a" -eq "$b" ]
:[
比较十进制整数的标准运算符。有些[
实现允许数字周围有空格,有些允许任意算术表达式,但这不是可移植的。便携,可以使用[ "$(($a))" -eq "$(($b))" ]
它。另请参阅[ "$((a == b))" -ne 0 ]
以下标准等效项(除了 POSIXly,仅当$a
和$b
包含整数常量时才指定行为):
((a == b))
从KSH以及在发现zsh
和bash
,返回true如果存储在算术表达式的评估$a
产率相同的数量的$b
。通常,这用于比较数字。请注意,shell 之间在如何计算算术表达式以及支持哪些数字方面存在差异(例如,bash 和 ksh 的某些实现/版本不支持浮点数或将带前导零的数字视为八进制)。
expr "$a" = "$b"
如果两个操作数都被识别为十进制整数(有些允许数字周围有空格),则进行数字比较,否则检查两个字符串运算符是否具有相同的排序顺序。对于$a
或像, ...$b
这样的expr
运算符(
,它也会失败substr
。
awk -- 'BEGIN{exit !(ARGV[1] == ARGV[2])}' "$a" "$b"
: 如果$a
和$b
被识别为数字(至少是十进制整数和浮点数,如 1.2、-1.5e-4,忽略前导尾随空格,有些还识别十六进制、八进制或任何识别的任何东西strtod()
),则执行数字比较。否则,取决于实现,它要么是字节到字节的字符串比较,要么expr
是strcoll()
比较,即是否$a
和$b
排序相同。
也可以看看:
¹包括GNU[
和[
的内置ksh
,bash
,yash
,一些但不是所有的ash
基壳和zsh
,但是请注意,在zsh
,=cmd
是一种特殊的文件名扩展操作者(在相同的上下文中展开为~user
是),该膨胀到对应的命令的路径,因此,除非您关闭equals
禁用该功能的选项,否则您需要编写它,[ "$a" '==' "$b" ]
否则您会收到=
找不到命令的错误。同为[ "$string" '=~' "$regexp" ]
Lri*_*Lri 22
这些在 bash 中是等价的:
[[ $x == "$y" ]]
[[ $x = "$y" ]]
[ "$x" == "$y" ]
[ "$x" = "$y" ]
Run Code Online (Sandbox Code Playgroud)
前两个 $x 变量不必被引用。Bash 在 [ 内部执行分词和路径名扩展,但不在 [[ 内部:
$ x='a b'
$ [ -s $x ]
-bash: [: a: binary operator expected
$ [[ -s $x ]]
$ ls
$ [ a = * ]
-bash: [: a: unary operator expected
$ [[ a = * ]]
$
Run Code Online (Sandbox Code Playgroud)
[[ $x = "$y" ]]
是一个字符串比较但是[[ $x = $y ]]
一个模式匹配表达式:
$ y='a*'; [[ aa = "$y" ]]; echo $?
1
$ y='a*'; [[ aa = $y ]]; echo $?
0
Run Code Online (Sandbox Code Playgroud)
-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
Run Code Online (Sandbox Code Playgroud)
另请参阅BashFAQ/031:测试、[ 和 [[ 之间有什么区别?.
小智 7
和=
都是==
运算符。在某些语言(如 C)中,一种用于为变量赋值,另一种用于比较值(算术表达式的结果)。事实上,这两个运算符正是算术求值中的运算符。A$((a=23))
是赋值,a$((a==23))
是算术比较。
$ echo "$((a=11)) $((a==23))" "$((a=23))" "$((a==23))"\n11 0 23 1\n
Run Code Online (Sandbox Code Playgroud)\n\n但在测试构造内部(所有test和[\xe2\x80\xa6]和[[\xe2\x80\xa6]])两个运算符的含义相同并执行相同的操作。
\n\n所以,所有这些选项:
\n\ntest "$a" = "$b"\n [ "$a" = "$b" ]\n [[ "$a" = "$b" ]]\ntest "$a" == "$b"\n [ "$a" == "$b" ]\n [[ "$a" == "$b" ]]\n
Run Code Online (Sandbox Code Playgroud)\n\n在bash中是等价的于测试二进制相等性(引用的变量)。如果正确的变量未加引号,则它可能会被解释为模式并进行相应的匹配:作为模式而不是文字字符串。
\n\n带引号的运算符\\=
和\\==
在 test 和 中使用时也是等效的[\xe2\x80\xa6]
。但引用的运算符\\==
在内部失败[[\xe2\x80\xa6]]
。
对于其他 shell,结果各不相同(正确的结果应该是Y -
(true false),不同于 0 (true) 和 1 (false) 的退出代码将报告为失败)\xc2\xa4
。某些 shell 会失败- -
(退出代码始终为 1)。
| dash ksh bash zsh \n test a = "$b" | Y - Y - Y - Y - \n [ a = "$b" ] | Y - Y - Y - Y - \n [[ a = "$b" ]] | \xc2\xa4 \xc2\xa4 Y - Y - Y - \n test a == "$b" | \xc2\xa4 \xc2\xa4 Y - Y - - - \n [ a == "$b" ] | \xc2\xa4 \xc2\xa4 Y - Y - - - \n [[ a == "$b" ]] | \xc2\xa4 \xc2\xa4 Y - Y - Y - \n test a \\= "$b" | Y - Y - Y - Y - \n [ a \\= "$b" ] | Y - Y - Y - Y - \n [[ a \\= "$b" ]] | \xc2\xa4 \xc2\xa4 Y - - - - - \n test a \\== "$b" | \xc2\xa4 \xc2\xa4 Y - Y - Y - \n [ a \\== "$b" ] | \xc2\xa4 \xc2\xa4 Y - Y - Y - \n [[ a \\== "$b" ]] | \xc2\xa4 \xc2\xa4 Y - - - - -\n
Run Code Online (Sandbox Code Playgroud)\n\n所有选项都可以在 ksh 中使用,带引号的运算符在 bash 和 zsh(在 内部[[\xe2\x80\xa6]]
)中失败,而未加引号的运算符\\=
在\\==
zsh(在 外部[[\xe2\x80\xa6]]
)中也失败。