Bash 如何正确使用[[=]]匹配全局?

Bash 如何正确使用[[=]]匹配全局?,bash,glob,Bash,Glob,Bash的manpage告诉我们,[[=]]匹配模式。因此,在Bash中,为什么不打印匹配的 Z=abc; [[ "$Z" == 'a*' ]] && echo 'matched' 但是,以下内容确实打印了匹配的: Z=abc; [[ "$Z" == a* ]] && echo 'matched' 这不是很落后吗?为什么没有引号的a*不能立即展开,列出当前目录中以字母a开头的任何文件名?此外,为什么引用的'a*'在任何情况下都不起作用?不能引用Glob模式使其

Bash的manpage告诉我们,
[[=]]
匹配模式。因此,在Bash中,为什么不打印
匹配的

Z=abc; [[ "$Z" == 'a*' ]] && echo 'matched'
但是,以下内容确实打印了匹配的

Z=abc; [[ "$Z" == a* ]] && echo 'matched'

这不是很落后吗?为什么没有引号的
a*
不能立即展开,列出当前目录中以字母a开头的任何文件名?此外,为什么引用的
'a*'
在任何情况下都不起作用?

不能引用Glob模式使其起作用

这也适用于不带引号的glob模式,而静态文本仍然是qupted的:

[[ "$Z" == "a"* ]] && echo 'matched'
matched

[[ "$Z" == "ab"* ]] && echo 'matched'
matched
手册页中的说明片段:

当==和!=使用运算符,字符串位于 运算符被视为一种模式,并根据 模式匹配下描述的规则。如果shell选项 如果启用nocasematch,则执行匹配时不考虑 字母字符的大小写。如果 字符串匹配(=)或不匹配(!=)模式,1 否则。图案的任何部分都可以引用,以迫使其 作为字符串匹配


此外,使用
[[
而不是
[
的原因之一是
[[[
是一个内置的shell,因此可以有自己的语法,不需要遵循正常的扩展规则(这就是为什么
[[
的参数不需要进行分词的原因)虽然现有的答案是正确的,但我认为它并不能说明全部情况

glob有两种用途。在
[[]]
构造中,glob和其他glob的行为有所不同,前者根据模式测试变量的内容,后者扩展为列出一系列文件。在这两种情况下,如果在字符周围加上引号,它将被逐字解释,而不是扩展

还值得一提的是,左侧的变量不需要在
[[
后面引用,因此您可以这样编写代码:

Z=abc; [[ $Z == a* ]] && echo 'matched'
也可以使用单个
=
,但是来自其他编码背景的人对
=
更熟悉,所以我个人更喜欢在bash中使用它。正如前面提到的,单个
=
的兼容性更广,因为它用于测试所有POSIX兼容shell中的字符串相等性,例如
>[“$a”=“abc”]
。因此,您可能更喜欢在bash中使用它


与往常一样,它包含了一些关于bash中模式匹配主题的好信息。

==
[[]]
中是完全可以接受的,顺便说一下,但是在
[]
中是错误的(bash将其作为扩展接受,但POSIX不要求支持它)。在所有非数学上下文比较中使用
=
意味着您的手指内存学习POSIX兼容方法。@Charles我已将您在评论中所说的一些内容纳入我的答案中。