I want to represent multiple conditions like this:
if [ ( $g -eq 1 -a "$c" = "123" ) -o ( $g -eq 2 -a "$c" = "456" ) ]
then
echo abc;
else
echo efg;
fi
but when I execute the script, it shows
syntax error at line 15: `[' unexpected,
where line 15 is the one showing if ....
What is wrong with this condition? I guess something is wrong with the ()
.
Using
/bin/bash
the following will work:Be careful if you have spaces in your string variables and you check for existence. Be sure to quote them properly.
Classic technique (escape metacharacters):
I've enclosed the references to
$g
in double quotes; that's good practice, in general. Strictly, the parentheses aren't needed because the precedence of-a
and-o
makes it correct even without them.Note that the
-a
and-o
operators are part of the POSIX specification fortest
, aka[
, mainly for backwards compatibility (since they were a part oftest
in 7th Edition UNIX, for example), but they are explicitly marked as 'obsolescent' by POSIX. Bash (see conditional expressions) seems to preempt the classic and POSIX meanings for-a
and-o
with its own alternative operators that take arguments.With some care, you can use the more modern
[[
operator, but be aware that the versions in Bash and Korn Shell (for example) need not be identical.Example run, using Bash 3.2.57 on Mac OS X:
You don't need to quote the variables in
[[
as you do with[
because it is not a separate command in the same way that[
is.I would have thought so. However, there is another alternative, namely:
Indeed, if you read the 'portable shell' guidelines for the
autoconf
tool or related packages, this notation — using '||
' and '&&
' — is what they recommend. I suppose you could even go so far as:Where the actions are as trivial as echoing, this isn't bad. When the action block to be repeated is multiple lines, the repetition is too painful and one of the earlier versions is preferable — or you need to wrap the actions into a function that is invoked in the different
then
blocks.In Bash: