Skip to content
Permalink
Browse files

tweak: yes-no-boolean-env-vars

  • Loading branch information...
samsalisbury committed Jul 18, 2019
1 parent 203f75e commit 6d4b4e96e0eb972e7edf7d3344c8b810498606be
Showing with 7 additions and 5 deletions.
  1. +7 −5 content/posts/yes-no-boolean-env-vars.md
@@ -13,10 +13,10 @@ I use `YES` and `NO` in environment variables to store Boolean values. I have co

- `0` and `1` are confusing in POSIX shells like bash, because `return 0` and `exit 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 treat `0` as false and `1` as true. Potential confusion abounds.
- `true` and `false` (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` or `YES` to be nonempty, then you can guarantee someone will try setting it to `false`, `0` or `NO`, 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.
- The _empty_ or _nonempty_ string is pretty bad. If you arbitrarily set it to `true`, `1` or `YES` to be nonempty, then you can guarantee someone will try setting it to `false`, `0` or `NO`, 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.
`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:

@@ -26,6 +26,8 @@ if [ $VAR = YES ]; then
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`.
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`.

So, after many years of writing and maintaining software, I have come to the firm belief that environment variables indicating the Boolean True or False should be stored in environment variables as `YES` or `NO` respectively. This simply sidesteps many potential readability and usability downsides with the other methods. You can be as strict as you like with casing, or ignoring/handling malformed values, but default to YES/NO and stop confusing yourself and others. (Well, me anyway.)
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!

0 comments on commit 6d4b4e9

Please sign in to comment.
You can’t perform that action at this time.