Environment variables make bad switches

September 2, 2009

Someday you may be faced with a deprecation situation where you need to add a compatibility switch to your program. When in this situation it may be tempting to resort to controlling things with an environment variable, instead of giving your program yet another command line option.

(The problem with using command line options is that they add clutter, complexity, or both to your documentation, including any usage stuff that the program prints.)

Unfortunately this is not a good way to add such switches to your program, especially compatibility switches. Beyond cluttering up the environment in general, environment variables tend to leak, winding up in the environment of everything that a script runs. If any of those other programs and scripts also use your program, they're suddenly running it with different options than they expect; this may not work too well, to put it one way.

(Yes, in theory people can set the environment variable just when they run your program directly. But in practice they won't because it's too annoying; instead they'll just set the environment variable once at the start of their script and it will propagate.)

Or in less words: using environment variables makes it possible for one script to accidentally poison a different script's use of your program. Spooky action at a distance is not an asset when writing shell scripts.

Comments on this page:

From at 2009-09-02 06:08:34:

Would your objection still hold if the program makes sure to unset the environment variable once it has seen it?

Aristotle Pagaltzis

By cks at 2009-09-02 17:38:06:

The problem isn't things run directly by the program; it's things run by the script that also runs the program.

Let me give an example. Suppose that the sort people decide that in the future it will number columns from 0, and if you want the old 1-based behavior you should set $POSIX_COLS. So you write a script:

... cmds ...
blah | sort -nr -k 3 | ...
... cmds ...
/usr/bin/someprog ...

Unknown to you, someprog is a shell script that also uses sort with column keys, and your distribution was dutiful enough to update it to use the new 0-based column ordering when they updated to using the new version of sort.

Kaboom. (Mysteriously, where someprog produces incorrect results out of the blue and perhaps only when run from inside your script.)

If you are lucky, this breaks immediately when you write the script. With less luck, this breaks when you upgrade your system to a new version of the distribution. (Ironically, you put $POSIX_COLS in in advance precisely to avoid breakage when you upgraded to something with this version of sort.)

If you are really unlucky, things don't break all of the time; sometimes things are such that the behavior differences you're poisoning with the environment variable don't matter to someprog's result. But sometimes they do, and you have even more mysterious explosions.

From at 2009-09-03 05:19:57:

Gotcha. That scenario never occurred to me – might be worth calling out explicitly.

Aristotle Pagaltzis

Written on 02 September 2009.
« How to deprecate bits of your program
Programming blindness and security »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Sep 2 02:39:45 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.