5

Can someone help me find out what I am doing wrong on this bash script. I am trying to using if statement inside case statement and bash is complaining syntax error.

findinfo() {
OPT1=$1
case  "$OPT1" in
   linux)
        echo "Setting environment"
        ESC="hello_linux" if [[ "$PROJN" == "ONE" ||  "$PROJN" == "two" ]]
        ;;
   Windows)
        echo "Setting environment"
        ESC="hello_windows" if [[ "$PROJN" == "ONE" ||  "$PROJN" == "two" ]]
        ;;
   Android)
        echo "Setting environment"
        ESC="hello_android" if [[ "$PROJN" == "ONE" ||  "$PROJN" == "two" ]]
        ;;
esac

}

Thanks

1
  • 4
    It has nothing to do with the case. Commented Jul 30, 2013 at 14:33

3 Answers 3

11

In bash, if must precede the then part:

if [[ "$PROJN" == "ONE" ||  "$PROJN" == "two" ]] ; then ESC=hello_linux ; fi

The "postfix" if is possible in Perl (and maybe somewhere else, too), but not in bash.

Sign up to request clarification or add additional context in comments.

1 Comment

Needs to be ESC=hello_linux, not ESC = hello_linux; the whitespace makes this a command ESC with two arguments, = and hello_linux.
8

The following syntax is a terser alternative:

[[ $PROJN = ONE || $PROJN = TWO ]] && ESC=hello_linux

...and the following is still shorter, and compliant with older shells:

case $PROJN in ONE|TWO) ESC=hello_linux ;; esac

1 Comment

@devnull No, I really don't. Better to quote when it isn't needed than not to quote when it is needed, though.
1

There's no problem using an if inside a case statement. It's that your if statements are a wee bit incorrect.

You had your if statement on the same line as your $ESC assignment. Doesn't work outside of a case doesn't work inside. Also, you need to use -o for the or in your if statements, and you need AT LEAST one line to execute if your if statement is true. (I just put an echo as a place holder).

It could be that this particular if statement should be outside of your case. I notice that they're all the same. No need to duplicate code in that case, just put your if after the esac.

By the way: You can do an or inside of an if in either one of these two ways:

if [[ "$PROJN" == "ONE" -o  "$PROJN" == "two" ]]

or

if [[ "$PROJN" == "ONE" ]] || [[  "$PROJN" == "two" ]]

And now back your regularly scheduled program...

findinfo() {
    OPT1=$1
    case  "$OPT1" in
       linux)
            echo "Setting environment"
            ESC="hello_linux" 
            if [[ "$PROJN" == "ONE" -o  "$PROJN" == "two" ]]
            then
                 echo "Here be dragons..."
            fi
            ;;
       Windows)
            echo "Setting environment"
            ESC="hello_windows" 
            if [[ "$PROJN" == "ONE" -o  "$PROJN" == "two" ]]
            then
                 echo "Here be dragons..."
            fi
            ;;
       Android)
            echo "Setting environment"
            ESC="hello_android" 
            if [[ "$PROJN" == "ONE" -o "$PROJN" == "two" ]]
            then
                 echo "Here be dragons..."
            fi
            ;;
    esac
}

3 Comments

Use of -o inside of [[ ]] is wrong; it should be the || operator.
To expand on Charles' comment, -o is also deprecated inside [ ]. In that case, you would use [ ] || [ ] instead (two separate test commands).
[[ '' -o true ]] is not "one of two ways", it's just (in bash) outright broken / entirely unsupported (at least in bash 3.2.57, as shipped by Apple; I haven't tested with all other extant releases). Try it: -bash: syntax error near `-o'. Which shell were you testing with which didn't throw such an error?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.