1. Overview
While comparing variables in Bash, we generally use single brackets ([ ]) and double brackets () interchangeably.
For example, we can use the expressions [ 3 -eq 3 ] or 3 -eq 3 while checking whether 3 is equal to 3. Both will be successful in performing the comparison. So, whatâs the difference between them?
In this tutorial, weâll discuss the differences between single and double brackets in Bash.
2. Main Differences
In this section, weâll briefly discuss the main differences between single and double brackets.
2.1. Single Brackets
[ is a shell built-in command that has always been available in Unix and Linux to evaluate expressions. It still exists for backward compatibility and POSIX compliance.
AD
Letâs verify that [ is a shell built-in command using the type command:
[ is an alternative command for the test built-in command. We can use them interchangeably:
The only difference between [ and test is that we must use the closing ] for surrounding the comparison.
2.2. Double BracketsThe double brackets, , were introduced in the Korn Shell as an enhancement that makes it easier to use in tests in shell scripts. We can think of it as a convenient alternative to single brackets.
Itâs available in many shells like Bash and zsh. However, double brackets arenât POSIX compliant.
AD
[[ is a shell keyword. Letâs check it using the type command:
3. Other Differences
In this section, weâll discuss the other differences between single and double brackets.
3.1. Comparison Operators****Itâs possible to use the comparison operators with the double brackets. Letâs use the less than operator (<) for lexicographic string comparison:
Here, we checked whether 1 is less than 2 using the less than operator. The comparison was successful. However, using single brackets instead of double brackets will give a syntax error:
In this case, Bash treated the < operator as a file redirection operator. Therefore, we must use the escape character (\) before the < operator for a successful comparison within single brackets:
AD
Now, the comparison using single brackets was successful.
Similarly, we must use the escape character before the greater than operator (>) for string comparison within single brackets.
On the other hand, we can use operators such as -eq**,**Â -ne**,**Â -gt**,**Â -lt**,**Â -ge**, and**Â -le for numeric comparison**.**
3.2. Boolean Operators****We must use the && operator for the logical AND operation and the || operator for the logical OR operation while using the double brackets.
Letâs check that 3 is equal to 3, and 4 is equal to 4:
However, we must use the -o and -a test operators for the logical OR and logical AND operations, respectively, while using single brackets.
Letâs repeat the last comparison we performed using single brackets this time:
The comparison is again successful. But we used -a instead of && because of single brackets.
AD
3.3. Grouping Expressions****We can group expressions within the double brackets using parentheses. One reason for grouping may be reading the expressions more easily:
Here, we grouped the expression, 2 -eq 2 && 1 -eq 1, using the parentheses. Then, we used the grouped expression, (2 -eq 2 && 1 -eq 1), as the second expression of && within the double brackets. The first expression of && was 3 -eq 3. The grouping was successful.
Now, letâs use the same expression using single brackets:
We used -a instead of && because of single brackets. However, we got a syntax error.
We must use the escape character before the opening and closing parentheses for a successful grouping. There must also be a space after and before the opening and closing parentheses:
Grouping the expressions using the parentheses within single brackets was successful in this case.
3.4. Pattern Matching****Itâs possible to use pattern matching with the double brackets. For example, we can use the wildcard * (asterisk) within the double brackets:
Here, we first assigned the value Alice to the shell variable name using the statement name=âAliceâ. Then, we checked whether the variable name includes the letter c using $name = *c*. * means zero or more characters. The result was successful, as expected.
AD
However, it isnât possible to use pattern matching within single brackets:
In this case, the only difference between the previous example is the single brackets. We replaced the double brackets in the previous example with the single brackets. There werenât any syntax errors, but pattern matching was unsuccessful as the exit status of [ $name = *c* ] && echo âName includes câ was 1.
3.5. Regular Expressions****Itâs also possible to use regular expressions within the double brackets:
We first assigned the value Alice to the shell variable name using the statement name=âAliceâ. Then, we checked whether the variable name starts with Ali using $name =~ ^Ali. The =~ built-in operator is used for matching the regular expressions. The caret (^) matches the beginning of a word. Hence ^Ali means the words beginning with Ali. As itâs apparent from the output, we could detect that the value of the shell variable starts with Ali.
Letâs try the same regular expression pattern using single brackets:
Now, we got an error. So, it isnât possible to use regular expressions within single brackets.
3.6. Word Splitting****Bash doesnât perform word splitting inside double brackets. For example, if a variable has a string value containing spaces, Bash doesnât split the string into words:
Here, we checked the existence of the file nonexistent file. The filename includes a space. We could directly use the variable, filename, within the double brackets as the double brackets didnât split the filename.
Letâs try it with single brackets:
We got an error in this case since the filename nonexistent file was split into two words, nonexistent and file. This is related to the IFS variable. If IFS isnât set, the shell splits the string when it encounters a space, tab, or newline.
We must put the variable in double quotes if we want to prevent the word splitting within single brackets:
Now, checking the existence of a filename containing spaces was successful within single brackets.
4. Conclusion
In this article, we discussed the differences between single and double brackets in Bash.
The single bracket is a built-in command thatâs older than the double bracket. The double bracket is an enhanced version of the single bracket. If we want the portability of scripts, we should prefer single brackets. However, using the double brackets is generally more convenient.
We saw that we could use comparison operators and boolean operators in both, apart from a few differences. The same thing is valid for grouping expressions and word splitting. However, using pattern matching and regular expressions is only possible in the double brackets.