![zsh 条件表达式中的模式匹配](https://linux22.com/image/164465/zsh%20%E6%9D%A1%E4%BB%B6%E8%A1%A8%E8%BE%BE%E5%BC%8F%E4%B8%AD%E7%9A%84%E6%A8%A1%E5%BC%8F%E5%8C%B9%E9%85%8D.png)
我在 zsh 的钩子函数中遇到模式匹配问题precmd
。我有以下内容:
precmd(){
local x='test'
if [ $x = '*test*' ]; then
echo 'hello'
fi
}
它永远不会打印你好。我已经用正常工作的正常代码测试了这段代码zsh test.zsh
,并且我尝试了不使用正则表达式precmd
,并且也可以很好地打印出来。关于为什么这不能按预期工作的任何线索吗?
$ zsh --version
zsh 4.3.11 RHEL
答案1
[ $x = '*test*' ]
测试扩展后的字符串$x
(即text
)是否等于扩展后的字符串'*test*'
(即 )*text*
。
测试变量的值是否x
与图案 *test*
,您需要使用=
或==
运算符zsh 条件表达式,其中写有双括号 [[ … ]]
。此外,模式中的特殊字符必须不加引号,否则它们代表自己。因此:
if [[ $x == *test* ]]; then …
条件表达式的语法与可在单括号内使用的表达式的语法类似[ … ]
,但并不完全相同。[
像普通命令一样被解析;事实上,它是一个带有单字符名称的内置命令,与test
内置但[
最后需要一个附加参数,该参数必须是]
.[[ … ]]
是一个独特的语法结构,允许它内部包含 shell 特殊字符。[ $x = *test* ]
将扩展*test*
到匹配文件名的列表(通配符),并且test
内置函数最终将解析其结果。作为条件表达式解析的一部分[[ $x = *test* ]]
进行解析*test*
,不会调用通配符。
答案2
*test*
不是有效的正则表达式模式。这*
是一个重复运算符,需要重复一些内容。这很可能是您想要的.*test.*
,尽管对于正则表达式来说这不是必需的,因为默认情况下它不是锚定的。你可以只寻找test
但是,您无法将正则表达式模式与=
运算符匹配,您需要=~
.
precmd () {
local x=test
if [[ $x =~ test ]]; then
echo 'hello'
fi
}