19

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
david
  • 741
  • 3
  • 10
  • 29

4 Answers4

28

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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • 1
    I would have sworn I tried this before without result.. probably did something different, thank you! – david Jun 29 '12 at 20:09
9

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

codeforester
  • 39,467
  • 16
  • 112
  • 140
4

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
Community
  • 1
  • 1
kojiro
  • 74,557
  • 19
  • 143
  • 201
0

In bash, to group conditionals using the [ ] construct you must surround each group using parenthesis. Each opening/closing parenthesis must be escaped and preceded/succeeded with a white space. See below:

if [ \( "$char" = "$;" \) -o \( "$char" = "$\\" \) -o \( "$char" = "$\" \) ]

As such, it's definitely best to follow everyone elses advice and use bash's newer [[ ]] construct. Lastly, as I understand it == is a relational operator intended to be used with-in arithmetic expressions. i.e. -

$((3==4))

Cameron Newham and Bill Rosenblatt, "Learning the bash Shell" Jan.1998

chunky_pie
  • 41
  • 4