user5507535
user5507535

Reputation: 1800

Bash - Simpler and more legible way to check if variable is true or false

In Bash 0 is true and any other number is false, like in C.

To test if a variable is true I'm currently doing:

is_on=0

if [ $is_on -eq 0 ]; then
    echo "It's on!"
else
    echo "It's off!"
fi

I want somethings more simple and readable, so I tried:

This doesn't because [ always returns 0:

is_on=0

if [ $is_on ]; then
    echo "It's on!"
else
    echo "It's off!"
fi

This also doesn't because [[ always returns 0:

is_on=0

if [[ $is_on ]]; then
    echo "It's on!"
else
    echo "It's off!"
fi

This also doesn't work:

is_on=0

if [ $is_on -eq true ]; then
    echo "It's on!"
else
    echo "It's off!"
fi

This inverses the logic:

is_on=0

if (( $is_on )); then
    echo "It's on!"
else
    echo "It's off!"  # Prints this!
fi

This works, but it's a string comparison:

is_on=true

if [ $is_on = true ]; then
    echo "It's on!"
else
    echo "It's off!"
fi

Is there a simpler and more legible way to check if a variable is true or false?

Upvotes: 1

Views: 2206

Answers (1)

KamilCuk
KamilCuk

Reputation: 141155

The interpretation of a value depends on the context. So some facts:

When doing some logic:

  • 0 means false,
  • nonzero means true.

When doing some action:

  • 0 exit status means success,
  • nonzero exit status means failure.

The if body executes when the command is successful. The if body executes when command exits with zero exit status.

The exit status of (( ... )) arithmetic expansion depends on the logical value of the last expression inside. A value of true means success and a value of false means failure (read that twice).

See man test and inspect STRING equivalent to -n STRING part. Also research bash builtins, bash shell arithemtic, bash exit status.

Is there a simpler and more legible way to check if a variable is true or false?

In a controlled environment I just use the variable value and execute the shell builtins false and true (that return an exit status of nonzero (failure) and zero (success) respectively):

is_on=true
if "$is_on"; then

In not controlled environment it's best to compare the strings to be protected against strange user input:

is_on="$1"
if [[ "$is_on" = 'true' ]]; then

If you wish to handle complicated cases, then write your own logic for it. In bash all variable values are strings, there are no other variable types (well, there are arrays of strings):

shopt +extglob
user_boolean_value_to_my_boolean_convention() {
    case "$1" in
    # 0 and 0000000 are false
    +(0)) echo false; ;;
    # any nonzero number or string true is true
    +([0-9])|T|t|[Tt][rR][uU][eE]) echo true; return; ;; 
    # all the rest is false
    *) echo false; ;;
    esac
}
is_on=$(user_boolean_value_to_my_boolean_convention "$1")
if "$is_on"; then
    

Upvotes: 3

Related Questions