Bash: Difference Between [ and [[ Operators

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
  # commands to execute if expression is true
else
  # commands to execute if expression is false
fi

Here, expression is a combination of options and arguments that are used to perform the test. Some common options 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
  # commands to execute if expression is true
else
  # commands to execute if expression is false
fi

The expression is a combination of options and arguments that are used to perform the test. The basic options are the same as the ones we've listed in the previous section when talking about 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 greater than 5 and y is less 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 less than 10"
fi

Overall, 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:

# Using the "[" operator
if [ -e "file.txt" ]
then
  echo "file.txt exists"
fi

# Using the "[[" operator
if [[ -e "file.txt" ]]
then
  echo "file.txt exists"
fi

Pretty much the same! Both of the above code samples check if the file file.txt exists and print a message if it does. However, while 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":

str1="My String"

# Using the "[" operator WITHOUT whitespaces
# This will return "Not equal" even though two strings are the same
if [ "$str1"="$str1" ] 
then 
  echo "Equal" 
else 
  echo "Not equal"
fi

# Using the "[" operator WITH whitespaces
# This will return "Equal", as expected
if [ "$str1" = "$str1" ] 
then 
  echo "Equal" 
else 
  echo "Not equal"
fi

# Using the "[[" operator WITHOUT whitespaces
# This will return "Equal", as expected
# Even without whitespaces
if [ "$str1"="$str1" ] 
then 
  echo "Equal" 
else 
  echo "Not equal"
fi

Another interesting difference 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 [:

# Using the "[" operator
if [ $x -eq 5 ]
then
  echo "x is equal to 5"
fi

# Using the "[[" operator
if [[ $x == 5 ]]
then
  echo "x is equal to 5"
fi
Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Both of the above code samples check if the variable x is equal to 5 and print a message if it does. The first code sample uses 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 [[:

# Using the "[" operator
if [ -z "$string" ]
then
  echo "string is empty"
fi

# Using the "[[" operator
if [[ -z $string ]]
then
  echo "string is empty"
fi

Both of the above code samples check if the variable string has a length of 0 and print a message if it does. However, while 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 the test 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.

Last Updated: January 19th, 2023
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Make Clarity from Data - Quickly Learn Data Visualization with Python

Learn the landscape of Data Visualization tools in Python - work with Seaborn, Plotly, and Bokeh, and excel in Matplotlib!

From simple plot types to ridge plots, surface plots and spectrograms - understand your data and learn to draw conclusions from it.

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms