ETOOBUSY 🚀 minimal blogging for the impatient
Shell variables tests: is it true?
TL;DR
Let’s continue with our shell test functions, this time understanding whether a variable is true or false.
Definitions
Let’s first state what we consider true: whatever Perl thinks of it. So:
- an undefined variable is false (see Shell variables tests: is it defined? for our definition of defined and undefined);
- an empty variable is false;
0
is false;- everything else is true.
Let’s define a few test variables:
unset F_UNSET
F_EMPTY=''
F_ZERO=0
T_ONE=1
T_WHATEVER='whatever'
Normalizing undefined variables
One thing that we have to be careful is applying test to an undefined variable, because the shell might have been set to be very picky about this. To this regard, it’s useful to look at parameter expansion:
${parameter:-[word]}
Use Default Values. If parameter is unset or null, the expansion of word (or an empty string if word is omitted) shall be substituted; otherwise, the value of parameter shall be substituted.
Hence, we can use 0
as the default value, so whatever variable state we
start from, false state will always be represented as 0
, simplifying the
test.
The test
These are two functions to implement that test:
is_var_true() {
local value
eval 'value="${'"$1"':-"0"}"'
[ "$value" != '0' ]
}
is_value_true() {
[ $# -gt 0 ] || return 1 # empty input list -> false
[ "${1:-"0"}" != '0' ]
}
The first tests whether a variable is true or false:
$ for v in F_UNDEF F_EMPTY F_ZERO T_ONE T_WHATEVER ; do
is_var_true "$v" && printf '%s: true\n' "$v" || printf '%s: false\n' "$v"
done
F_UNDEF: false
F_EMPTY: false
F_ZERO: false
T_ONE: true
T_WHATEVER: true
The second tests whether the value of the first input parameter (if any) is true or false:
$ is_value_true "$F_EMPTY" && printf 'F_EMPTY: true\n' || printf 'F_EMPTY: false\n'
F_EMPTY: false
$ is_value_true "$F_ZERO" && printf 'F_ZERO: true\n' || printf 'F_ZERO: false\n'
F_ZERO: false
$ is_value_true "$T_ONE" && printf 'T_ONE: true\n' || printf 'T_ONE: false\n'
T_ONE: true
$ is_value_true "$T_WHATEVER" && printf 'T_WHATEVER: true\n' || printf 'T_WHATEVER: false\n'
T_WHATEVER: true
Sounds like the functions work!