Search code examples
bashif-statementevaluationunsetis-empty

Why an unset variable gets evaluated as 0 in bash if statement


I'm trying to understand why an unset variable gets evaluated as 0. in some scripts im writing the variable will be set only if needed and some time it does not. so this kind of behave will result with incorrect output. does it mean i must preset all my variables or at least add check that they are set ?

#!/bin/bash
#myvalue=0  #comment to simulate an unset variable.

if [[ $myvalue -eq 0 ]] ; then
   echo "OK"
fi

result with OK:

bash -x test.sh
+ [[ '' -eq 0 ]]
+ echo OK
OK

Solution

  • The -eq operator inside [[ ... ]], since it only applies to integer values, triggers arithmetic evaluation of its operands. In an arithmetic expression, unset variables default to 0. A more obvious demonstration of arithmetic evaluation:

    $ if [[ 3 -eq "1 + 2" ]]; then echo equal; fi
    equal
    

    Note that in your example, you don't even need to expand the parameter first; the arithmetic evaluation will do it for you:

    $ if [[ myvalue -eq 0 ]]; then echo equal; fi
    equal
    $ myvalue=3
    $ if [[ myvalue -eq 3 ]]; then echo equal; fi
    equal
    

    Also, this is specific to the bash [[ ... ]] command. With POSIX [, -eq does not trigger arithmetic evaluation.

    $ if [ "$myvalue" -eq 0 ]; then echo equal; fi
    bash: [: : integer expression expected
    $ if [ myvalue -eq 0 ]; then echo equal; fi
    bash: [: myvalue: integer expression expected