来自 bash 手册,用于条件表达式
string1 == string2 string1 = string2
如果字符串相等则为 True。
当与该命令一起使用时
[[
,它将执行如上所述的模式匹配(请参见第 3.2.4.2 节 [条件结构],第 10 页)。这里的“模式匹配”是什么意思?
这里的“模式匹配”与什么相对?
如果不与其他命令一起使用
[[
,但与其他命令一起使用,“this”会执行什么操作?
'=' 应与命令一起使用
test
以保持 posix 一致性。POSIX 这里说了什么?
反对的句子是什么?
可以
==
用test
命令吗?我试过了,看来是的。除此以外还能
=
和其他命令一起使用吗test
?我尝试了和=
,似乎可以。[[
[
==
和之间有什么区别=
?在 Bash 4.3 中,我尝试将
==
和=
与test
,[[
, 和一起使用[
。在我看来==
是=
一样的。可以在任何条件表达式中互换使用吗
==
?=
谢谢。
答案1
POSIXtest
(或[ ... ]
) 只知道只有一个等号的:
s1= s2
如果字符串 s1 和 s2 相同则为真;否则为假。
但 Bash 也接受双等号,尽管内置帮助不承认这一点(手动的做):
$ help test | grep -A1 =
STRING1 = STRING2
True if the strings are equal.
STRING1 != STRING2
True if the strings are not equal.
至于其他的贝壳,就看情况了。嗯,尤其是 Dash 是这里最顽固的一个:
$ dash -c '[ x == x ] && echo foo'
dash: 1: [: x: unexpected operator
但
$ yash -c '[ x == x ] && echo foo'
foo
$ busybox sh -c '[ x == x ] && echo foo'
foo
$ ksh93 -c '[ x == x ] && echo foo'
foo
中zsh
,=something
是一个文件名扩展something
运算符,如果在中找到,则扩展为命令的路径,除非关闭$PATH
该选项(例如模拟其他 shell 时),并且也适用于或在简单命令的参数中找到时,例如,至少必须引用前导那里:equals
==
=~
test
[
=
$ zsh -c 'echo =ls'
/usr/bin/ls
$ zsh +o equals -c 'echo =ls'
=ls
$ zsh --emulate ksh -c 'echo =ls'
=ls
$ zsh -c '[ x == x ] && echo foo'
zsh:1: = not found
$ zsh -c '[ x "==" x ] && echo foo'
foo
我的 Debian 上的 GNU coreutils 的外部test
/实用程序支持(但是[
==
手动的不承认这一点),而 OS X 上的则不然。
因此,使用test
/时[ .. ]
,请使用它=
,因为它受到更广泛的支持。
随着[[ ... ]]
构造, 和=
都是==
相等的(至少在 Bash 中),并且运算符的右侧被视为一种模式,就像在文件名 glob 中一样,除非它被引用。 (文件名未在 内扩展[[ ... ]]
)
$ bash -c '[[ xxx == x* ]] && echo foo'
foo
但当然这种构造不是标准的:
$ dash -c '[[ xxx == x* ]] && echo foo'
dash: 1: [[: not found
$ yash -c '[[ xx == x* ]] && echo foo'
yash: no such command ‘[[’
虽然 Busybox 有它,但它不进行模式匹配:
$ busybox sh -c '[[ xx == xx ]] && echo yes || echo no'
yes
$ busybox sh -c '[[ xx == x* ]] && echo yes || echo no'
no
答案2
在 bash 中,关于相等有四个条件:
=
内部(或测试)简单且最基本(且仅与 posix 兼容)[ … ]
:
仅执行两个字符串的相等(逐字节)。STRING1 = STRING2 True if the strings are equal.
这扩展
==
。它仍然(仅)执行相等测试。$ [ aaaa == aaaa ] && echo yes yes $ [ aaaa == a* ] && echo yes $
请注意,
a*
如果密码中存在匹配的文件名,则未加引号的内容将扩展为一个(或多个)文件名。具体来说:名为 aaaa 的现有文件将使代码输出 yes。如果没有匹配的文件,则精确比较会受到 failedglob 和 nullglob shell 选项的影响。=
a 内的A[[
完全等同于:==
a 内部的A[[
既进行逐字节匹配,又进行全局匹配。如果右侧的字符串或变量
==
被引用,则进行字节比较。如果所有字节都相等,则结果为[[
“好”(0)。如果字符串(或者在所有情况下最好是:变量)未加引号,则按照文件名 glob 中的方式执行匹配。
$ [[ aaaa == "aaaa" ]] && echo yes yes $ a='aaaa' $ [[ aaaa == "$a" ]] && echo yes yes $ a='a*' $ [[ aaaa == "$a" ]] && echo yes $ $ a='a*' $ [[ aaaa == $a ]] && echo yes yes
有趣的是,未引用的内容aaaa
也有效:
$ a='aaaa'
$ [[ aaaa = $a ]] && echo yes
yes
发生这种情况是因为变量内的字符串没有任何可扩展的全局字符*
, +
, ?
,[
以及扩展的(如果激活)|
,@
和!
。但这通常是一个冒险的选择。