The [[ ]] test syntax is both more flexible and less error-prone:
Does not require parameter expansions on the left-hand side to be quoted.
Always treats expansions to empty strings as "" rather than string-splitting them out of existence (and thus potentially causing syntax errors).
Allows pattern tests by using an unquoted glob expression on the right-hand side of an = test. ([[ $foo = 'Hello '* ]])
Allows regexp tests by using an unquoted regular expression on the right-hand side of an =~ test. For maximum flexibility and compatibility across versions, the regex should be in a variable: re='foo.*bar'; [[ $var =~ $re ]]. Stores groups within matched regexes to the ${BASH_REMATCH[@]} array.
Allows substring tests by using a quoted value on the right-hand side of an =~ operator: [[ $foo =~ "$substring" ]] determines whether the literal contents of the $substring variable exist anywhere within $foo.
Allows standard grouping operators and short-circuiting boolean logic within the test itself, as so: [[ a = b && ( c = d || e = f ) ]]
The better behaviour around quoting and empty expansions alone makes this worthwhile.
Taking advantage of the additional capabilities is going to require a little more effort:
We need a way to express the glob, regex and substring matches
To use the grouping and logic operators, we need to recognise test expressions at a compound level. Currently test expressions are recognised at a simple expression level.
The
[[ ]]
test syntax is both more flexible and less error-prone:""
rather than string-splitting them out of existence (and thus potentially causing syntax errors).=
test. ([[ $foo = 'Hello '* ]]
)=~
test. For maximum flexibility and compatibility across versions, the regex should be in a variable:re='foo.*bar'; [[ $var =~ $re ]]
. Stores groups within matched regexes to the${BASH_REMATCH[@]}
array.=~
operator:[[ $foo =~ "$substring" ]]
determines whether the literal contents of the$substring
variable exist anywhere within$foo
.[[ a = b && ( c = d || e = f ) ]]