Compound 'if' statements with multiple expressions in Bash

22,973

Solution 1

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

Solution 2

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

Solution 3

Charles' answer is correct in that it shows you how to do logical operations on commands within (and without, for that matter) an if statement, but it looks more like you want to use case here:

case $char in
    \;|\\|\') echo found;;
    *) echo 'not found';;
esac
Share:
22,973

Related videos on Youtube

david
Author by

david

Updated on July 09, 2022

Comments

  • david
    david almost 2 years

    I would like to recreate something like this

    if ( arg1 || arg2 || arg 3) {}
    

    And I did got so far, but I get the following error:

    line 11: [.: command not found
    
    if [ $char == $';' -o $char == $'\\' -o $char == $'\'' ]
    then ...
    

    I tried different ways, but none seemed to work. Some of the ones I tried.

    • SourceSeeker
      SourceSeeker almost 12 years
      There's probably not any need to use $''.
    • Charles Duffy
      Charles Duffy almost 12 years
      Using == inside of [ ] isn't actually valid POSIX sh, even though bash allows it. Use only a single = for string comparison tests.
  • Charles Duffy
    Charles Duffy almost 12 years
    Good call -- admittedly, I looked a bit much at the literal question as opposed to intent.
  • david
    david almost 12 years
    I would have sworn I tried this before without result.. probably did something different, thank you!