Size: 1688
Comment: remove non-POSIX-safe use of -a/-o
|
Size: 1795
Comment: Use syntax "commandA" t refer to any command instead of two words "test A", which may be confused with test(1) command.
|
Deletions are marked like this. | Additions are marked like this. |
Line 7: | Line 7: |
if test A && test B || test C; then | if commandA && commandB || commandC; then |
Line 9: | Line 9: |
# or with test(1) calls: if [ testA ] && [ testB ] || [ testC ]; then ... |
|
Line 15: | Line 20: |
if test A && { test B || test C; }; then | if commandA && { commandB || commandC; }; then |
Line 44: | Line 49: |
if [[ n>0 && n<10 ]] | if [[ $n>0 && $n<10 ]] |
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:
# Bourne if commandA && commandB || commandC; then ... # or with test(1) calls: if [ testA ] && [ testB ] || [ testC ]; then ...
The grouping is implicit in this case, because AND (&&) has a higher precedence than OR (||). If we need explicit grouping, then we can use curly braces:
# 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 and KornShell have different, more powerful comparison commands with slightly different (easier) quoting:
ArithmeticExpression for arithmetic expressions, and
NewTestCommand for string (and file) expressions.
Examples:
# Bash/ksh if (( (n>0 && n<10) || n == -1 )) then echo "0 < $n < 10, or n==-1" fi
or
# Bash/ksh if [[ ( -f $localconfig && -f $globalconfig ) || -n $noconfig ]] then echo "configuration ok (or not used)" fi
Note that the distinction between numeric and string comparisons is strict. Consider the following example:
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 comparision "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.