The builtin test operator
In bash (and other shells) you can use the [[ construct
From the bash manpage:
[[ expression ]]
Return a status of 0 or 1 depending on the evaluation of the
conditional expression expression. Expressions are composed of
the primaries described below under CONDITIONAL EXPRESSIONS.
Word splitting and pathname expansion are not performed on the
words between the [[ and ]]; tilde expansion, parameter and
variable expansion, arithmetic expansion, command substitution,
process substitution, and quote removal are performed. Condi‐
tional operators such as -f must be unquoted to be recognized as
primaries.
So no word splitting and pathname expansion.
A little example⌗
First we have some setting up to do
$ mkdir ~/tmp/zz
$ touch ~/tmp/zz/111
$ echo ~/tmp/zz/*
/home/miekg/tmp/zz
Well, lets test [[
$ if [[ tmp/zz/* = tmp/zz/111 ]]; then echo OK; else echo NOK; fi
NOK
NOK - that’s correct, because [[ will not do pathname expansion.
The other way around
$ if [[ tmp/zz/111 = tmp/zz/* ]]; then echo OK; else echo NOK; fi
OK
Huh, OK
?
Why
To see why bash behaves as it does, the best explanation comes from
the ksh
manual. Yes, the K shell.
In the section ‘Conditional Expressions’ of ksh’s manual page
string = pattern True, if string matches pattern.
Aha, so the right side of a =
test is a pattern and a such
it is expanded even though we put it in a [[ construct.
In the bash manual we just have
string1 == string2
True if the strings are equal. = may be used
in place of == for strict POSIX compliance.
Which is not entirely correct.
In zsh (which is of course the shell) in the section ‘CONDITIONAL EXPRESSIONS’ it is also correct
string = pattern
string == pattern
true if string matches pattern. The ‘==’ form is the preferred
one. The ‘=’ form is for backward compatibility and should be
considered obsolete.
So this might be something worth considering.