Bash的手册页教导[[ == ]]
匹配模式。因此,在Bash中,为什么以下内容不能打印matched
?
Z=abc; [[ "$Z" == 'a*' ]] && echo 'matched'
但以下确实打印matched
:
Z=abc; [[ "$Z" == a* ]] && echo 'matched'
这不是完全落后的吗?为什么没有引号的a*
不会立即展开以列出当前目录中以字母a开头的任何文件名?此外,为什么引用的'a*'
在任何情况下都不起作用?
答案 0 :(得分:2)
不得引用Glob模式以使其有效。
这也应该只用于引用的glob模式,而静态文本仍然是被查询的:
[[ "$Z" == "a"* ]] && echo 'matched'
matched
[[ "$Z" == "ab"* ]] && echo 'matched'
matched
手册页中的解释片段:
当使用==和!=运算符时,右边的字符串 运算符被认为是一种模式并根据其匹配 模式匹配下面描述的规则。如果是shell选项 启用了nocasematch,执行匹配而不考虑 字母字符的情况。如果返回值为0 字符串匹配(==)或不匹配(!=)模式和1 除此以外。可以引用该图案的任何部分以强制它 匹配为字符串。
此外,使用[[
而不是[
的原因之一是[[
是一个内置的shell,因此可以有自己的语法,不需要遵循正常的扩展规则(这就是为什么[[
的参数不受分词限制的原因)。
答案 1 :(得分:1)
虽然现有答案是正确的,但我并不相信它能说出完整的故事。
Globs有两种用途。在[[ ]]
构造内的globs之间的行为存在差异,该构造测试变量的内容与模式和其他globs,其扩展以列出一系列文件。在任何一种情况下,如果你在字符周围加上引号,它将按字面解释而不是扩展。
还值得一提的是,左侧的变量不需要在[[
之后引用,因此您可以像这样编写代码:
Z=abc; [[ $Z == a* ]] && echo 'matched'
也可以使用单个=
但==
看起来比其他编码背景的人更熟悉,所以我个人更喜欢在bash中使用它。如上所述in the comments,单=
是更广泛兼容的,因为它用于测试所有符合POSIX的shell中的字符串相等性,例如[ "$a" = "abc" ]
。出于这个原因,你可能也喜欢在bash中使用它。
与往常一样,Greg's wiki包含有关bash中模式匹配主题的一些很好的信息。