Introduction
In bash, the [
and [[
operators are used for comparison and testing. The [
operator is an alias for the test
command, which is used to check the properties of files or to compare strings or integers. The [[
operator is a more advanced version of the test command. It allows you to perform more powerful comparisons and tests, such as regular expression matching and string manipulation.
In this article, we’ll take a look at the difference between those very similar operators in Bash. We’ll assume you already know the basics of both operators, and you just want to make an educated decision on when to use which one.
[ Operator – Back to Basics
The [
operator, also known as the test command, is a built-in command in bash that is used to perform various tests on files and strings. It can be used to check for the existence of files, compare values, and test the properties of strings. The operator must be enclosed in a whitespace or be escaped with a backslash.
Let’s quickly take a look at the basic syntax for the [
operator:
if [ expression ]
then
else
fi
Right here, expression
is a mixture of choices and arguments which are used to carry out the check. Some widespread choices used with the [
operator include:
-e file
to check if a file exists-f file
to check if a file is a regular file-d file
to check if a file is a directory-z string
to check if a string has a length of 0-n string
to check if a string has a non-zero length
[[ Operator – Back to Basics
The [[
operator is an extended version of the [
operator in Bash. It is used to perform various tests and arithmetic operations, and has a more flexible syntax. It is not as strictly dependent on whitespace or backslashes around it, as the [
operator.
The basic syntax for the [[
operator is almost identical to the [
operator syntax we’ve discussed above:
if [[ expression ]]
then
else
fi
The expression
is a mixture of choices and arguments which are used to carry out the check. The essential choices are the identical as those we have listed within the earlier part when speaking in regards to the [
operator.
In addition to these options, the [[
operator supports additional string and arithmetic operations such as regular expressions matching, logical and/or operators, and comparison operators without the need for -eq
, -lt
, etc:
if [[ $string =~ "regex" ]]
then
echo "string matches the regex"
fi
if [[ $x > 5 && $y < 10 ]]
then
echo " x is bigger than 5 and y is lower than 10"
fi
The [[
operator also supports the assignment and arithmetic operations, this makes it more versatile than the [
operator:
if [[ ( x+=5) -lt 10 ]]
then
echo "x is now lower than 10"
fi
Total, the [[
operator is a more recent addition to Bash and is more powerful than [
operator in terms of functionality and flexibility, it offers improved readability, better performance, and additional functionality to perform various tests and operations.
Note: Be aware that the behavior of [[
might be slightly different than [
operator, so it’s important to check the documentation if you are not sure which to use!
[ and [[ Operators – Head to Head Comparison
Now, after we recapped the basics of both operators, we can compare them head-to-head. Let’s take a look at several use cases of [
and [[
operators and compare the syntax.
First of all, take a look at the example where we want to check for the existence of the file.txt
:
if [ -e "file.txt" ]
then
echo "file.txt exists"
fi
if [[ -e "file.txt" ]]
then
echo "file.txt exists"
fi
Just about the identical! Each of the above code samples test if the file file.txt
exists and print a message if it does. Nonetheless, whereas the [
operator requires whitespace or a backslash around it, the [[
operator does not.
Note: The [
operator is the alias for the test
built-in function in Bash, and all of the built-in functions accept arguments as an array of whitespace-separated strings. That’s why the [
operator requires whitespaces around each of its arguments!
The previous example wasn’t sufficient at illustrating the need for whitespaces when using the [
operator, so, let’s choose another, more illustrative example. We’ll compare two strings that are the same, and expect the script to return "Equal"
:
str="My String"
if [ "$str1"="$str1" ]
then
echo "Equal"
else
echo "Not equal"
fi
if [ "$str1" = "$str2" ]
then
echo "Equal"
else
echo "Not equal"
fi
if [ "$str1"="$str2" ]
then
echo "Equal"
else
echo "Not equal"
fi
One other attention-grabbing distinction between [
and [[
is that the [[
operator supports more operators than [
. For example, it can use the ==
comparison operator rather than the -eq
operator used with [
:
if [ $x -eq 5 ]
then
echo "x is the same as 5"
fi
if [[ $x == 5 ]]
then
echo "x is the same as 5"
fi
Try our hands-on, sensible information to studying Git, with best-practices, industry-accepted requirements, and included cheat sheet. Cease Googling Git instructions and really be taught it!
Each of the above code samples test if the variable x
is the same as 5
and print a message if it does. The primary code pattern makes use of the -eq
operator with the [
operator and the second code sample uses the ==
operator with the [[
operator to check for equality.
Note: The same can be applied to -lt
and <
, -gt
and >
, and other operators mentioned in the sections above.
Another handy feature of the [[
operator is that we don’t need to wrap strings with quotes when using [[
:
if [ -z "$string" ]
then
echo "string is empty"
fi
if [[ -z $string ]]
then
echo "string is empty"
fi
Each of the above code samples test if the variable string
has a size of 0
and print a message if it does. Nonetheless, whereas the [
operator requires that string
be enclosed in quotes(""
), the [[
operator doesn’t.
In general, the [[
operator offers more functionality, improved readability, and better performance than the [
operator. The [[
operator supports additional string and arithmetic operations, regular expressions, logical and/or operators, and comparison operators without the need for -eq
, -lt
, etc, assignment and arithmetic operation, allowing for more complex and powerful tests in Bash scripts.
Note: It is important to note that the behavior of [[
might be slightly different than [
operator and in certain scenarios [
is more appropriate to use – most notably when you need to run your scripts on old systems.
Comparison Recap
Finally, let’s recap several key differences in functionality and performance between the [
and [[
operators in bash.
Functionality
-
The
[
operator is a synonym for thetest
command and is used to perform tests on files and strings. It supports a limited set of options and has a more restrictive syntax. -
The
[[
operator is an extended version of the[
operator, and is more powerful in terms of functionality. It supports additional string and arithmetic operations, regular expressions, logical and/or operators, and comparison operators without the need for-eq
,-lt
, etc, assignment and arithmetic operations, allowing for more complex and powerful tests in Bash scripts. It also allows more flexible syntax.
Performance
-
The
[
operator is generally considered to be slower than the[[
operator as it requires more parsing, and also requires whitespace or backslashes around it, which can lead to additional overhead. -
The
[[
operator, on the other hand, is faster and more efficient, as it has a more flexible syntax and does not require additional characters for parsing.
Compatibility
-
The
[[
operator is a more recent addition to Bash, and as such, it is not always guaranteed to be available on older systems. It is mostly used in more recent versions of Bash. -
The
[
operator, on the other hand, has been around for a longer time and is widely supported across different systems.
Conclusion
All-in-all, after reading this article you’ll be able to make an educated decision on what operator suits your needs the best.
Both operators are used to perform tests and make decisions in Bash scripts. In general, it’s recommended to use [[
operator for improved functionality, readability, and performance. However, in the case of scripts that need to be run on older systems or cross-platform, it is better to stick with the [
operator, as it is more widely supported.