I use YES
and NO
in environment variables to store Boolean values. I have come to the conclusion that this is in some way optimal after trying all the other obvious options and finding that each has readability flaws:
0
and1
are confusing in POSIX shells like bash, becausereturn 0
andexit 0
usually mean “success” (the command did not fail) which we think of as truthy. Likewise,1
or any other non-zero number is treated as failure in these contexts, which intuitively feels falseish. Most other programming languages like C treat0
as false and1
as true. Potential confusion abounds.true
andfalse
(strings) both work, and are not too bad. However there are shell builtin functions with these same names, which can occasionally be confusing. Why entertain that risk?!- The empty or nonempty string is pretty bad. If you arbitrarily set it to
true
,1
orYES
to be nonempty, then you can guarantee someone will try setting it tofalse
,0
orNO
, and be gravely disappointed at the result. - The set or not set variable is the worst of all worlds. It inherits the same issues as the empty or nonempty string, but has some extra quirks all of its own. Unsetting a variable in your own interactive shell isn’t that bad
unset VAR
and you’re done. However, passing that command down through a stack of Makefiles, scripts, Docker run invocations etc is impossible. Some might try to be clever and set the var to empty, but it doesn’t work. Time to get editing that stack of turtles. Be kind, give your users a knob they can use at a distance.
YES
and NO
cannot be confused with shell builtins, or implicit integer conversations to bools, and the words map rather intuitively to true and false respectively.
The comparison I usually use in practice is:
if [ $VAR = YES ]; then
echo You said yes!
fi
Completely ignoring the potential NO
value, treating anything that’s not YES
as false. Coupling this with default false values for options dictated by env vars usually makes this safe. If you really need a decision to have been made (i.e. it is not safe to default to false) then you might want to fail if it’s not set explicitly to YES
or NO
.
Using YES
and NO
simply sidesteps many potential readability and usability downsides with the other methods.
Am I right or am I wrong? Let me know in the comments!