Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

If want to express the following test in shell (sh) :

if ( a == 1 && ( b == 1 || b == 2 )) { ... }

So far, the best I have been able to write is this :

if [[ $a -eq 1 ]]; then
  if [[ $b -eq 1 || $b -eq 2 ]]; then
     ...
  fi
fi

I don't know how to compound && and || with correct precedence. Googling has not given me any answer (tutorials only give basic examples, if any)

What is the syntax to combine those two if into one ?

share|improve this question
1  
Any reason to not use ksh? Then your initial code would require only one more pair of parenthesis: if (( a == 1 && ( b == 1 || b == 2 ))); then :; fi –  manatwork Jan 10 '12 at 17:18

2 Answers 2

up vote 7 down vote accepted

Note that [[ ]] is not in either Bourne or POSIX sh. For true sh syntax, there are several ways to do this.

Using only one [ ] pair

if [ 1 -eq "$a" -a \( 1 -eq "$b" -o 2 -eq "$b" \) ]; then
    # ...
fi

or Avoiding the POSIX -a and -o options1

if [ 1 -eq "$a" ] && { [ 1 -eq "$b" ] || [ 2 -eq "$b" ]; }; then
    # ...
fi

1 One reason for avoiding -a and -o is maximum portability - not all test or [ implementations can handle more than 4 arguments, which is precisely what you get if you chain expressions with -a and -o and \( \).

share|improve this answer
    
My scripts have the #! /bin/sh shebang, and the default shell is ksh. Why would sh not be used ? –  Offirmo Jan 10 '12 at 16:45
1  
@Offirmo If you declare your script as /bin/sh, it is incorrect to write the script using features not in sh. You should be aware that ksh is NOT sh, but rather a superset of sh. If you take your ksh-but-declared-as-sh script to a system where sh is not a symlink to ksh, it may break. You can avoid that problem by making sure your script matches the declaration. –  jw013 Jan 10 '12 at 17:03
    
I thought that setting /bin/sh as shebang would make my scripts invoked via /bin/sh. Do you mean that my default shell (ksh) ignore the shebang and interpret it directly ? –  Offirmo Jan 10 '12 at 18:04
    
@Offirmo You are correct: a shebang of /bin/sh will invoke /bin/sh. The problem is /bin/sh does not accept [[. You can either not use [[ or use a shell that does accept [[, e.g. ksh, as your shebang. –  jw013 Jan 10 '12 at 22:25
    
That's puzzling... my shebang are all /bin/sh and I use [[ ]] everywhere and it works... Must be some strange config on my RedHat 5... Found it ! /bin/sh is a symbolic link pointing to /bin/bash on my machine. I'll update my shebangs accordingly. Thanks for the info. –  Offirmo Jan 11 '12 at 9:01

I tried some syntax and found that

if [[ $a -eq 1 ]] && [[ $b -eq 1 || $b -eq 2 ]]; then
 ...
fi

is working.

share|improve this answer
    
this works for bash version above 4. –  Nikhil Mulley Jan 10 '12 at 17:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.