nested logical expression in bash shell

Please tell me how to nest logical expressions in bash. I would like to nest logical expressions for arguments of the "test" command on bash.

The following pseudo-code shows my intention.

// pseudo code

if (exp1 AND (exp2 OR exp3))
{
  Output true;
}
else
{
  Output false;
}

The following bash code failed.

if test 1 -eq 1 -a ( 2 -eq 2 -o 2 -eq 3 )
then
  echo "true"
else
  echo "false"
fi

The above bash code ended up with the following error message.

syntax error near unexpected token `('

Many thanks, in advance.

if [[ 1 -eq 1 && ( 2 -eq 2 || 2 -eq 3 ) ]]
then
  echo "true"
else
  echo "false"
fi

--ahamed

-a and -o are deprecated... For POSIX compliancy use:

if test 1 -eq 1 && ( test 2 -eq 2 || test 3 -eq 3 )
then
  echo "true"
else
  echo "false"
fi

or the synonym:

if [ 1 -eq 1 ] && ( [ 2 -eq 2 ] || [ 3 -eq 3 ] );
1 Like

hi,

Shell & Utilities - Single UNIX Specifications warns to not use them if script's input may be such strings.
I didn't find where it tells they're deprecated.

edit: or is it what means "deprecated"

They advise not to use them, but the specification also says they have been marked obsolescent and that script should be converted:

test

1 Like

Using the recommended operators how can i write the following?

if NOT [ $var -eq 'a' || $var = 'b' || $var = 'c' ]
then
 ....
fi

I want to keep the '||' clause and do not want to translate into

if [ $var -ne 'a' && $var -ne 'b' && $var -ne 'c' ]

because using 'NOT' equivalent ahead upfront is much easier to understand the logic

I am using Korn shell

Thanks,
-srinivas y.

I think either of these are acceptable in Ksh or bash depending on your preference/need for single or double bracketed expressions:

if   ! [ $1 == "foo" ] || [ $1 == "bar" ]
then
    echo true
else
    echo false
fi

if  ! [[ $1 == "foo"  ||  $1 == "bar" ]]
then
    echo true
else
    echo false
fi
1 Like

This is not the same, for the single bracket version; there should be single = signs and double quotes around the left variable and the negation operator should work on the entire logical comparison, so one would need to use grouping to accomplish this:

if ! ( [ "$1" = "foo" ] || [ "$1" = "bar" ] )
then

The use of parentheses means using a subshell, so I think it is more efficient to use block grouping:

if ! { [ "$1" = "foo" ] || [ "$1" = "bar" ] ;}
then

Or use the logical equivalent:

if [ "$1" != "foo" ] && [ "$1" != "bar" ]
then

The equivalent using the features of test that are obsoleted in the POSIX specification would be:

if [ ! \( "$1" = "foo" -o "$1" = "bar" \) ]
then

-or-

if ! [ "$1" = "foo" -o "$1" = "bar" ]
then

---------- Post updated at 11:42 ---------- Previous update was at 09:24 ----------

if ! { [ "$var" = a ] || [ "$var" = b ] || [ "$var" = b ] ;}
then

If you are writing a Korn shell script and do not need POSIX compliancy you can use this:

if ! [[ $var == a || $var == b || $var == c ]]
then

To answer post #1 :
The correct syntax in your context is:

if [ 1 -eq 1 -a \( 2 -eq 2 -o 2 -eq 3 \) ]
then
  echo "true"
else
  echo "false"
fi

Note that the parentheses are escaped because we want to give them to "test" and not start a subshell.

@Scrutinizer
The word is "depreciated" not "deprecated" !
Anyway there is no way that the "-a" and "-o" syntax or the brackets will be "depreciated" no matter how often the Posix police mention it.

@methyl: Deprecation

1 Like

Oops. I stand corrected. Word must have crept in from America. No such meaning in a UK English dictionary.

will post my question in new thread