134

I have defined the following variable:

myVar=true

now I'd like to run something along the lines of this:

if [ myVar ]
then
    echo "true"
else
    echo "false"
fi

The above code does work, but if I try to set

myVar=false

it will still output true. What might be the problem?

edit: I know I can do something of the form

if [ "$myVar" = "true" ]; then ...

but it is kinda awkward.

Thanks

1

2 Answers 2

193

bash doesn't know boolean variables, nor does test (which is what gets called when you use [).

A solution would be:

if $myVar ; then ... ; fi

because true and false are commands that return 0 or 1 respectively which is what if expects.

Note that the values are "swapped". The command after if must return 0 on success while 0 means "false" in most programming languages.

SECURITY WARNING: This works because BASH expands the variable, then tries to execute the result as a command! Make sure the variable can't contain malicious code like rm -rf /

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

3 Comments

Might add not to forget the ; fi at the end. So it's if $myVar ; then ... ; fi
and if ! $myVar ; then ... ; fi gives the converse
The case answer (from @Jens) is safer and doesn't require a fork to test a simple variable.
76

Note that the if $myVar; then ... ;fi construct has a security problem you might want to avoid with

case $myvar in
  (true)    echo "is true";;
  (false)   echo "is false";;
  (rm -rf*) echo "I just dodged a bullet";;
esac

You might also want to rethink why if [ "$myvar" = "true" ] appears awkward to you. It's a shell string comparison that beats possibly forking a process just to obtain an exit status. A fork is a heavy and expensive operation, while a string comparison is dead cheap. Think a few CPU cycles versus several thousand. My case solution is also handled without forks.

3 Comments

true and false are built-in commands in most shells. Invoking them is unlikely to require a fork() call.
Calling which true in bash, zsh, ksh, dash, and fish, it seems that only zsh has true and false as built-ins. Seems like a sensible thing for shells to implement though!
don't use which -- that only searches the $PATH -- use type -a true -- true and false are builtin to bash and ksh and dash

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.