0

I tried the code in this SO post - How to evaluate a boolean variable in an if block in bash? and it does not work. It looks like there are no booleans in BASH. Is there a flawless workaround which lets me set and check booleans in BASH ?

My code -

#!/bin/bash
flag=true
if [ $flag ]
echo 'True'
#flag=false
#echo 'Now changed to false' 
fi

Even if flag=false in line 2, output is still True. Why ?

1
  • Please see Jens answer in the link provided. if $myVar; then ... ;fi logic seems to have a security flaw. Commented Aug 1, 2013 at 22:35

3 Answers 3

10

Try without square brackets, like this

#!/bin/bash
flag=true
if $flag ; then
   echo 'True'
   #flag=false
   #echo 'Now changed to false' 
fi
Sign up to request clarification or add additional context in comments.

6 Comments

+1 for correct answer. Note also that it's "#!", not "!#", on the first line of a script.
What is the difference between brackets and no brackets ?
Without brackets, it attempts to execute the value as a command. It works here because the true command returns true, and the false command returns false. You can also set flag="rm -r /*", and have the condition delete all your files.
Please see Jens answer in the link provided. if $myVar; then ... ;fi logic seems to have a security flaw.
@blasto, whether it's a security issue or not depends on the script and where the value of the variable comes from. It certainly could be a problem sometimes.
|
4

It evaluates to true because of this part of 'man test' -

 [ expression ]
         string        True if string is not the null string.

You need to use something like -

#!/bin/bash
flag=1
if [ ${flag} -eq 1 ]
then
    echo 'True'
    #flag=0
    #echo 'Now changed to false' 
fi

4 Comments

btw, why did you put flag in {} brackets ? cant we do "$flag" == 1 instead ?
${flag} and $flag are the same. You shouldn't use double quotes and == here, though, because you want to do a numeric comparison, not a string comparison.
@AnsgarWiechers - thanks. but, isn't numeric and string comparison the same thing here ? We are just creating a flag and checking its state.
@blasto. I use ${} out of habit. It prevents bash from trying to interpret the contents of the variable.
0

Setting

To set a bash variable $subject to boolean true or false, use subject=true or subject=false. To set a vash variable to null, use subject= or subject=$() or unset subject

Testing

The use of single brackets and no brackets is suspicious and I've found several discrepancies in the expected behavior around how empty strings, null values, and integer 0 and 1 are evaluated.

First, defining the correct behavior of a strict boolean test as follows:

  • The if test for boolean true evaluates to true only when the subject is boolean true. Such a test will evaluate to false for any other value, including 1 and any string with value 'true'
  • The if test for false evaluates to true only when the subject is boolean false. Such a test will evaluate to false for any other value, including 0, null, and an empty string ''

The correct method to accomplish this is to use double square brackets and explicitly test against true or false as follows:

if [[ ${subject} = true ]]; then { ... } fi  # only if boolean true
if [[ ${subject} = false ]]; then { ... } fi # only if boolean false

Note that if you use such a test for boolean true (or false), an else block will not only cover the opposite condition, but also the entire set of possible values that are not boolean false (or true) respectively.

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.