Difference between parentheses and brackets in Bash conditionals

BashIf Statement

Bash Problem Overview


While learning a bit about [tag:bash], I come to see four types of ways of working with if statements:

  • Single Parenthesis - ( ... )
  • Double Parenthesis - (( ... ))
  • Single Square Bracket - [ ... ]
  • Double Square Brackets - [[ ... ]]

What is the difference between Parenthesis and Square Brackets in bash.

Bash Solutions


Solution 1 - Bash

The tests you had listed :

  • Single Parenthesis - ( ... ) is creating a subshell
  • Double Parenthesis - (( ... )) is for arithmetic operation
  • Single Square Bracket - [ ... ] is the syntax for the POSIX test
  • Double Square Brackets - [[ ... ]] is the syntax for bash conditional expressions (similar to test but more powerful)

are not exhaustive, you can use boolean logic

if command; then ...

too, because the commands have exit status. In bash, 0 is true and > 0 is false.

You can see the exit status like this :

command
echo $?

See :

http://wiki.bash-hackers.org/syntax/basicgrammar
http://wiki.bash-hackers.org/syntax/arith_expr
http://mywiki.wooledge.org/BashGuide/TestsAndConditionals

Solution 2 - Bash

The shell itself only runs the command and evaluates its exit code. A zero exit code signifies success; all other values indicate failure.

if command; then
    : things to do if the exit code from command was 0
else
    : things to do if it was not 0
fi

while command; do
    : things to do if the exit code was 0
done

The command [ (aka test) is very commonly used in conditionals, because the original Bourne shell lacked built-in operators to check if a string was empty or a file existed. Modern shells have this command built in, and many shells have an extended and modernized version [[, but this is not properly portable to POSIX sh and should thus be avoided for portable scripts. This related question explains the differences between the two in more detail.

The notation (( ... )) introduces an arithmetic context. Again, this was something which was not part of the original Bourne shell (it had a dedicated external tool expr for these things) but modern shells have this built in. The result code of an arithmetic expression is 0 if the result of the arithmetic evaluation was not 0 (or an error).

The notation ( command ) creates a subshell and evaluates command in that. There are situations where this is actually necessary and useful, but if you are only just learning the syntax, you are unlikely to need this.

... In fact, in the majority of scripts I have seen this used in a conditional, it was clearly unnecessary.

Another antipattern to look out for is

command
if [ $? = 0 ]; then
    : things
fi

You should almost never need to examine $? explicitly, and in particular, comparing it to zero is something if and while specifically do for you behind the scenes. This should simply be refactored to

if command; then
    : ...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLuis AlvaradoView Question on Stackoverflow
Solution 1 - BashGilles QuenotView Answer on Stackoverflow
Solution 2 - BashtripleeeView Answer on Stackoverflow