I am having trouble with pattern matching in zsh's hook function precmd
. I have the following:
precmd(){
local x='test'
if [ $x = '*test*' ]; then
echo 'hello'
fi
}
which does not print hello ever. I've tested this code with a normal zsh test.zsh
that works fine, and I've tried w/o the regex in precmd
and got things to print out fine as well. Any clue as to why this isn't working as expected?
$ zsh --version
zsh 4.3.11 RHEL
Best Answer
[ $x = '*test*' ]
tests whether the string resulting from expanding$x
, which istext
, is equal to the string resulting from expanding'*test*'
, which is*text*
.To test whether the value of the variable
x
matches the pattern*test*
, you need to use the=
or==
operator of zsh conditional expressions, which are written within double brackets[[ … ]]
. Furthermore special characters in the pattern must be unquoted, otherwise they stand for themselves. Thus:The syntax of conditional expressions is similar to the syntax of expressions that you can use within single brackets
[ … ]
, but not identical.[
is parsed like an ordinary command; in fact, it's a built-in command with a one-character name, which is identical to thetest
builtin except that[
requires an additional argument at the end which must be]
.[[ … ]]
is a distinct grammatical construct, which allows it to have shell special characters inside.[ $x = *test* ]
would expand*test*
to the list of matching file names (globbing) and thetest
builtin would end up parsing the result of that.[[ $x = *test* ]]
parses*test*
as part of conditional expression parsing which does not invoke globbing.