<> == How can I group expressions in an if statement, e.g. if (A AND B) OR C? == The portable (POSIX or Bourne) way is to use multiple `test` (or `[`) commands: {{{#!highlight bash # Bourne if commandA && commandB || commandC; then ... # or with test(1) calls: if [ testA ] && [ testB ] || [ testC ]; then ... }}} When they are shell operators between commands (as opposed to the `[[...]]` operators), `&&` and `||` have equal precedence, so processing is left to right. If we need explicit grouping, then we can use curly braces: {{{#!highlight bash # Bourne if commandA && { commandB || commandC; }; then ... }}} What we should ''not'' do is try to use the `-a` or `-o` operators of the `test` command, because the results are undefined. [[BASH]], zsh and the KornShell have different, more powerful comparison commands with slightly different (easier) quoting: * ArithmeticExpression for arithmetic expressions, and * NewTestCommand for string (and file) expressions. Examples: {{{#!highlight bash # Bash/ksh/zsh if (( (n>0 && n<10) || n == -1 )) then echo "0 < $n < 10, or n==-1" fi }}} or {{{#!highlight bash # Bash/ksh/zsh if [[ ( -f $localconfig && -f $globalconfig ) || -n $noconfig ]] then echo "configuration ok (or not used)" fi }}} Note that contrary to the `&&` and `||` ''shell'' operators, the `&&` operator in `((...))` and `[[...]]` has precedence over the `||` operator (same goes for `[`'s `-a` over `-o`), so for instance: {{{#!highlight bash [ a = a ] || [ b = c ] && [ c = d ] }}} is '''false''' because it's like: {{{#!highlight bash { [ a = a ] || [ b = c ]; } && [ c = d ] }}} (left to right association, no precedence), while {{{#!highlight bash [[ a = a || b = c && c = d ]] }}} is '''true''' because it's like: {{{#!highlight bash [[ a = a || ( b = c && c = d ) ]] }}} (`&&` has precedence over `||`). Note that the distinction between numeric and string comparisons is strict. Consider the following example: {{{#!highlight bash n=3 if [[ $n > 0 && $n < 10 ]] then echo "$n is between 0 and 10" else echo "ERROR: invalid number: $n" fi }}} The output will be "ERROR: ....", because in a ''string comparison'' "3" is bigger than "10", because "3" already comes after "1", and the next character "0" is not considered. Changing the square brackets to double parentheses {{{(( ))}}} makes the example work as expected. ---- CategoryShell