Appearance
Bash Double Bracket Test
The [
command can be used in shell scripts to test an expression. In Bash, this can be done with [[
as well, which offers more features. However [[
is not POSIX compliant and does not work in many shell implementations.
Resources:
Word Splitting and Glob Expansion
The [
command requires that you wrap your multi-word string variables with quotes. Without quotes, the variable will be subject to word splitting. With [[
, word-splitting will not be performed, even without quotes.
bash
filename="foo bar.txt"
# -e checks if a file exists
[ -e $filename ] && echo "file exists"
# The command above is equivalent to `test -e foo bar.txt` which will not run correctly
[ -e "$filename" ] && echo "file exists"
# The command above is equivalent to `test -e "foo bar.txt" and runs as expected
[[ -e $filename ]] && echo "file exists"
# Runs as expected
Similarly, variables with *
symbol needs to be wrapped in quotes for [
tests to prevent the shell from performing glob expansion. This isn't necessary for [[
tests.
Handling Special Characters
For [
tests, some characters need to be escaped as they carry special meanings. For example, <
and >
are redirection commands. These will need to be escaped if we want these symbols to be interpreted as comparison operators. Escaping these characters isn't necessary with [[
tests.
As string comparison operators, these symbols compare strings according to their place in the alphabetical order. b > a
should return true as 'b' comes after 'a'.
bash
[ a > b ] && echo "true"
# The above will output 'true' and a file 'b' will be created
# as the redirection command '>' took effect
[ a \> b ] && echo "true"
# The above has no output. Behaves as expected
[[ a > b ]] && echo "true"
# The above has no output. Behaves as expected
+++
Expression grouping with (...)
needs to be escaped for [
tests, but not in [[
tests. See below:
bash
[ \(expression1 && expression2\) && expression3 ]
[[ (expression1 && expression2) && expression3 ]]
Conditional Evaluation
Conditional evaluation (AND, OR) works differently for [
vs. [[
tests. The following shows the syntax for both types of tests.
bash
# AND evaluation
[ $var1 = a -a $var2 = b ] && echo "true"
[ $var1 = a ] && [ $var2=b ] && echo "true"
[[ $var1 = a && $var = b ]] && echo "true"
# OR evaluation
[ $var1 = a -o $var2 = b ] && echo "true"
[ $var1 = a ] || [ $var2 = b ] && echo "true"
[[ $var1 = a || $var2 = b ]] && echo "true"
&&
and ||
does not work within a single test expression for [
tests. They either need to be split or replaced with -a
, -o
operators.
Regex Matching
[[
tests offer regex matching. This is not available in [
tests.
bash
[[ $answer =~ ^y(es)?$ ]]
# returns true if answer is either 'y' or 'yes'
Pattern Matching
Pattern matching only works in [[
tests, and not available in [
. This is achieved with the use of *
wildcard character
bash
input="abcdfoobarefgh"
[[ $input = *"foobar"* ]] && echo "true" # This is equivalent to string contains check
[[ $input = "abcd"* ]] && echo "true" # Checks if string is prefixed with 'abcd'