I'm referring to *nix command line applications primarily, where you want to permanently modify the behavior from defaults.

Environmental variables are easily understood and implemented, usually requiring the user to modify their ~/.bashrc for a permanent change. However, namespace collision might be a problem (but unlikely if you're careful).

On the other hand, a lot of programs use ~/.programrc config files.

Is it simply verbosity? If your program only has 2 configuration settings, then a simple export APP_SETTING=1 works just fine. However if you're starting to offer 5+ options then it should be time to start looking into a config file?

2 Answers
2

Writing a config file requires write permission on the file system (in fact, it requires a file system in the first place!). Environment variables can be set even if you are running a rescue system from a CD.

Environment variables can be set quickly and temporarily just for one invocation, which is much better for use in small shell scripts. (Rewriting and re-rewriting a config file risks destroying the original settings if the process doesn't terminate correctly. Temporary values die automatically.)

A config file can be passed around easily to some other user or pre-installed with a distribution. Telling someone how to use environment variables is much harder. You wouldn't believe how much harder it is to get normal people to type CDG_VERBOSITY=5 cdg correctly then just cdg.

Environment variables may or may not get inherited properly if your program farms out work to other processes. A config file is always there.

There can be surprisingly low limits on the size of the environment that can be passed to a process on some systems. The file system is much, much more forgiving.

If you need to change settings after program start, telling a process to re-read its config file is a well-known idiom. Changing the environment of a running process can be trickier.

Reading a config file hits the disk, which is massively slower than reading from the environment. A config file would be grossly inappropriate for something like grep, which is usually invoked on data that are entirely in memory.