0

Im trying to nest if else bash statements using [[..]] but I seem to be running into issues:

my line:

[[ $WRD == "tmp" ]] && tmpFlag=1 || [[ $someOtherVar == "test" ]] && tempFlag=2 || tempFlag=3

Basically, if WRD is tmp, then flag is 1, else if $someOtherVar is test, then the flag is 2 and if all else fails, then set the flag to 3.

But this level of nesting doesnt work.

  • If I provide WRD as tmp, flag is set to 2. [WRONG]
  • If I do not provide a WRD and $someOtherVar isn't test, then it is set to 3. [CORRECT].
  • If I do not provide a WRD and $someOtherVar is test, then it is set to 3. [WRONG]
3
  • Think about operator precedence of && and ||. The tmpFlag=1 is treated as a statement and command and fails, so the || is executed. Explain please why it would not be better to write this with if ... elsif .. else ... fi instead? Commented Dec 14, 2019 at 2:44
  • It would be better to write it with that.. but I was trying to see if it was possible to do it using the [[...]] functionality Commented Dec 14, 2019 at 2:45
  • It doesn't work the way you expect. If WRD is set to tmp then the statement [[ $WRD == "tmp" ]] && tmpFlag=1 || [[ $someOtherVar == "test" ]] succeeds (as a "whole"), so tempflag=2 is executed. Commented Dec 14, 2019 at 2:47

3 Answers 3

2

Unlike boolean operators in other languages, && and || have the same precedence.

The tmpFlag=1 is treated as a statement and command and while it does not fail, there is nothing in bash that associates the || with the immediate previous term before a preceding &&, so the || is executed.

Here is a shorter snippet that makes that clear:

 tempFlag=1 ||echo nooooo && echo hello

Causes the echo hello to appear, because of echo noooo not because of the success of tempFlag=1.

Also consider this:

true && echo yes || echo no && echo yeeees || echo noooooo

give you both:

yes
yeeees

Explain please why it would not be better to write this with if ... elsif .. else ... fi instead? –

Also, why not use [ ]?

I would do it like this, much clearer:

if [ "$WRD" = "tmp" ] ; then
    tempFlag=1
elif [ "$someOtherVar" = "test" ] ; then
    tempFlag=2
else
    tempFlag=3
fi

PS, I also notice you have a typo, your first tmpFlag was supposed to be tempFlag. It doesn't change the behavior of course.

Another PS: using && and || instead of if .. elif .. fi is not really about the "[[ ]] functionality". You'd have the same problem if your were using the old test "[ ] functionality".

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

1 Comment

OK, as for the failure of space and tab, what I usually do is of course put quotes around $WRD, I forgot that.
0

The test && command1 || command2 syntax does work as expected but if you append another command with &&, it breaks due to the operator precedence.
As a workaround, you can make compound commands as command2 by surrounding them with { ... }.
Then would you please try the following:

[[ $WRD == "tmp" ]] && tmpFlag=1 || { [[ $someOtherVar == "test" ]] && tmpFlag=2 || tmpFlag=3; }
echo "$tmpFlag"
  • if I provide WRD as tmp, flag is set to 1.
  • if I do not provide a WRD and $someOtherVar is test, then flag is set to 2.
  • if I do not provide a WRD and $someOtherVar isn't test, then flag is set to 3.

I'm not sure if it is readable than if .. else .. syntax but it works.
Note that you have a typo in the variable name tmpFlag.

Hope this helps.

Comments

0

Just use braces for each of the "primary" options:

{ [[ $WRD == "tmp" ]] && tmpFlag=1 ; } || 
  { [[ $someOtherVar == "test" ]] && tempFlag=2; } || 
  tempFlag=3

Comments

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.