Suppose I have the following Bash snippet:
if [[ "$foo" == *"$bar"* ]] ; then
echo 'condition is true'
fi
In English, you might describe the above code with: if bar
is a substring of foo
then...
However, how come when we switch the sides of the condition, we don't get the same results?
if [[ *"$bar"* == "$foo" ]] ; then
echo 'condition is true'
fi
Perhaps I have a misunderstanding of when the wildcard is evaluated?
It's an explicit design decision. Here's man bash
:
When the == and != operators are used, the string to the right of the operator is considered a pattern and matched according to the rules described
Pathname expansion is not performed in [[ .. ]]
, so regular rules around that don't apply.
Treating both as a pattern would be pretty strange. Should [[ a* == [a]* ]]
be true because the right pattern matches the left string, false because the left pattern does not match the right string, or true because both patterns match the same set of strings?
The == comparison operator behaves differently within a double-brackets :
[[ $foo == 0* ]] # True if $foo starts with foo "0" (wildcard matching).
[[ $foo == "0" ]] # True if $foo is equal to 0* (literal matching).
This works because bash's builtin [[
operator treats the right-hand-side of an == test as a pattern:
When the
==
and!=
operators are used, the string to the right of the operator is used as >a pattern and pattern matching is performed.
the test
builtin tests wheather strings are equal the [[expression]]
syntax adds comparison test for string operators, the >
and <
operators compare strings for oder (i.e :"aa" < "bb")
. the operator tests for pattern match not just equality [[ string = pattern ]]
is true if string matches pattern, this operator is not symmertical , the pattern must appear on the right side of the equal sign, i.e [[ foo = a* ]]
is true (=0),whereas
[[ a* = foo ]]
is false(=1)
[[ "foo" == f* ]] && echo $? # 0
[[ f* == "foo" ]] && echo $? || echo $? # 1
How come [[ $foo == $bar ]]
is true and [[ $bar == $foo ]]
is false?
The ==
operator is not symmetrical. It takes a string on the left
and a pattern on the right. However, if you double quote the right
hand side, which removes the special meaning of pattern match
characters, then this becomes a string comparison so that
[[ "$foo" == "bar" ]]
and [[ "$bar" == "$foo" ]]
are equivalent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With