来自 bash 手册,用于条件表达式
Run Code Online (Sandbox Code Playgroud)string1 == string2 string1 = string2
如果字符串相等,则为真。
当与该
[[
命令一起使用时,它会执行上述模式匹配(参见第 3.2.4.2 节 [条件构造],第 10 页)。
“模式匹配”在这里是什么意思?
什么是“模式匹配”?
如果不[[
与其他命令一起使用,但与其他命令一起使用,“this”执行什么?
'=' 应该与
test
posix 一致性命令一起使用。
POSIX 在这里说什么?
反对的句子是什么?
可以==
和test
命令一起使用吗?我试过了,似乎是的。
可以=
用除此之外其它命令中使用test
?我试着=
用[[
和[
,似乎是肯定的。
==
和之间有什么区别=
?
在bash 4.3,我试图==
和=
同test
,[[
和[
。==
并且=
看起来是一样的我。
可以==
和=
在任何条件表达式互换使用?
谢谢。
ilk*_*chu 12
POSIX test
( 或[ ... ]
) 只知道有一个等号的那个:
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.
Run Code Online (Sandbox Code Playgroud)
至于其他贝壳,则视情况而定。好吧,尤其是 Dash 是这里的顽固者:
$ dash -c '[ x == x ] && echo foo'
dash: 1: [: x: unexpected operator
Run Code Online (Sandbox Code Playgroud)
但
$ yash -c '[ x == x ] && echo foo'
foo
$ busybox sh -c '[ x == x ] && echo foo'
foo
$ ksh93 -c '[ x == x ] && echo foo'
foo
Run Code Online (Sandbox Code Playgroud)
zsh
这里有点奇怪,==
被认为是一个特殊的运算符,所以它必须被引用:
$ zsh -c '[ x == x ] && echo foo'
zsh:1: = not found
$ zsh -c '[ x "==" x ] && echo foo'
foo
Run Code Online (Sandbox Code Playgroud)
我的 Debian 上的 GNU coreutils的 external test
/[
实用程序支持==
(但手册不承认这一点),而 OS X 上的不支持。
因此,使用test
/ [ .. ]
,=
因为它得到了更广泛的支持。
使用[[ ... ]]
构造,两者=
和==
都相等(至少在 Bash 中),并且运算符的右侧被视为一个模式,就像在文件名 glob 中一样,除非它被引用。(文件名不在 内扩展[[ ... ]]
)
$ bash -c '[[ xxx == x* ]] && echo foo'
foo
Run Code Online (Sandbox Code Playgroud)
但当然,这种结构不是标准的:
$ dash -c '[[ xxx == x* ]] && echo foo'
dash: 1: [[: not found
$ yash -c '[[ xx == x* ]] && echo foo'
yash: no such command ‘[[’
Run Code Online (Sandbox Code Playgroud)
虽然 Busybox 有它,但它不进行模式匹配:
$ busybox sh -c '[[ xx == xx ]] && echo yes || echo no'
yes
$ busybox sh -c '[[ xx == x* ]] && echo yes || echo no'
no
Run Code Online (Sandbox Code Playgroud)
小智 6
在 bash 中,关于相等有四个条件:
\n\n=
内部(或测试)的简单和最基本(并且仅 posix 兼容)[ \xe2\x80\xa6 ]
:
\n仅执行两个字符串的相等(逐字节)。
\nRun Code Online (Sandbox Code Playgroud)\nSTRING1 = STRING2\n True if the strings are equal.\n
扩展的 ==
. 它仍然(仅)执行相等测试。
$ [ aaaa == aaaa ] && echo yes\nyes\n\n$ [ aaaa == a* ] && echo yes\n$\n
Run Code Online (Sandbox Code Playgroud)\n\n请注意,a*
如果密码中存在匹配的文件名,则未加引号的内容将扩展为一个(或多个)文件名。具体来说:名为 aaaa 的现有文件将使代码输出 yes。如果没有匹配的文件,则精确比较会受到 failedglob 和 nullglob shell 选项的影响。
a=
内的 A[[
完全等同于:
a==
内部的 A[[
既进行逐字节匹配,又进行全局匹配。
如果右侧的字符串或变量==
被引用,则进行字节比较。如果所有字节都相等,则结果为[[
“好”(0)。
如果字符串(或者在所有情况下最好是:变量)未加引号,则按照文件名 glob 中的方式执行匹配。
\n\n$ [[ aaaa == "aaaa" ]] && echo yes\nyes\n\n$ a=\'aaaa\'\n$ [[ aaaa == "$a" ]] && echo yes\nyes\n\n$ a=\'a*\'\n$ [[ aaaa == "$a" ]] && echo yes\n$\n\n$ a=\'a*\'\n$ [[ aaaa == $a ]] && echo yes\nyes\n
Run Code Online (Sandbox Code Playgroud)有趣的是,未引用的内容aaaa
也有效:
$ a=\'aaaa\'\n$ [[ aaaa = $a ]] && echo yes\nyes\n
Run Code Online (Sandbox Code Playgroud)\n\n发生这种情况是因为变量内的字符串没有任何可扩展的全局字符*
, +
, ?
,[
以及扩展的(如果激活)|
,@
和!
。但这通常是一个冒险的选择。