Compound if statements with multiple expressions in Bash

Bash's [[ ]] and (( )) are more powerful and flexible than [ ].

  • [[ ]] is for strings and (( )) is for integer logic and arithmetic
  • && and || operators can be used inside [[ ]] and (( )), and () can be used for grouping
  • No need to quote variable expansions inside [[ ]] or (( )) - Bash doesn't do word splitting or globbing in these contexts
  • Inside (( )), there is no need for a $ behind variable names to expand them
  • [[ ]] and (( )) can span multiple lines, without the need for a line continuation with \

Using these, we can write clean, readable, and more reliable code.

Examples

Compound statements with integers

a=1 b=2 c=3
((a == 2 || (b == 2 && c == 3))) && echo yes                   # yields yes

Compound statements with strings

x=apple y=mango z=pear
[[ $x == orange || ($y == mango && $z == pear) ]] && echo yes  # yields yes

[ equivalents for the above statements, using {}

[ "$a" -eq 2 ] || { [ "$b" -eq 2 ] && [ "$c" -eq 3 ]; }
[ "$x" == orange ] || { [ $y == mango ] && [ "$z" == pear ]; }

Related

  • Is double square brackets [[ ]] preferable over single square brackets [ ] in Bash?
  • How to use double or single brackets, parentheses, curly braces
  • Comparing integers: arithmetic expression or conditional expression on Unix & Linux
  • Test for non-zero length string in Bash: [ -n “$var” ] or [ “$var” ]
  • Conditional Expressions - Bash Manual

For Bash, you can use the [[ ]] form rather than [ ], which allows && and || internally:

if [[ foo || bar || baz ]] ; then
  ...
fi

Otherwise, you can use the usual Boolean logic operators externally:

[ foo ] || [ bar ] || [ baz ]

...or use operators specific to the test command (though modern versions of the POSIX specification describe this XSI extension as deprecated -- see the APPLICATION USAGE section):

[ foo -o bar -o baz ]

...which is a differently written form of the following, which is similarly deprecated:

test foo -o bar -o baz