
Ask HN: Cmd line parameters, env variables or config files? - gtirloni
What do you prefer and why?
======
__d
I think that this is a false opposition thing: they're all good, and you
should have all of them.

Command-line parameters, especially single character ones, are a quick and
easy way to request ad hoc changes of program behavior. They're also common
across many utilities, so you can expect that -d to display debugging output,
and -h to be a hostname, -p to be a port number, -n to do a dry-run, etc.

Configuration files are good for persistent, per-program settings. If you
always want altered behavior, a configuration file is easier than constantly
adding command-line options. Note that this implies that command-line options
should override configuration file options, and that a --no-foo variant can be
useful.

Environment variables are good for long-term, multi-program configurations:
EDITOR, DISPLAY, LANG, PAGER, TERM, etc. It can be good to have these
available as command-line options (eg. -display, for Xt-based apps), but
generally it's ok to override them with env FOO=bar program. Also of note:
container orchestration systems are generally able to set environment
variables, but might not be able to create (and later remove) a configuration
file.

So ... it's often not the case that _every_ program option should have all
three means of control, but most programs should use all three mechanisms,
depending on what type of optional behavior is being controlled.

~~~
jolmg
> Environment variables are good for long-term, multi-program configurations

Not just that. They're also useful for when a program is called by another
program and you want to control something about its invocation without having
to modify the source code of that other program each time.

For example, I might use a different value for LESS when calling man than when
calling git.

------
wahern
In order of preference:

1) Command line parameters, particularly when an application is using getopt()
or getopt_long(). Among other things, they make it easier to test and debug an
application. For example, daemonization and sandboxing should be controllable
from the command-line, assuming the application has such logic. That said, use
of nonstandard option syntax in the Go community, for example, is maddening.

2) Environment variables. Personally I usually support environment variables
which mirror command lines option. For example, FOO_B or FOO_BAR might be
equivalent to specifying a -b or --bar command line option.

3) Configuration file. But please don't make it necessary if at all possible.

If I'm writing an application supporting all 3, then the above ordering is
also the precedence ordering. A command line option overrides an environment
variable which overrides a configuration file setting.

Command line options are constraining because of the flat namespace and
because they become unwieldy in large numbers. But that's a good thing. They
force you to think critically about semantics and default behaviors, and to
make meaningful choices.

Simple key-value configuration files, like JSON or YAML, are IMO the worst
choice of all. They just become dumping grounds. If you're going to support a
configuration file format, use an expressive, declarative syntax. An HN poster
the other day said that systemd's ini file format was declarative. No, it's
not! The abstract configuration of systemd is declarative, but systemd's
configuration _syntax_ is anything but. Devising an expressive syntax and
structure is difficult, but that's the point. It's a way to examine and
reexamine your application behavior without ever writing a single line of
code. As far as parsing the configuration file, most high-level languages have
good PEG libraries which make it easy to write parsers for ad hoc grammars.
For C if you're not comfortable using the classic yacc framework then maybe
that's a strong hint to avoid a configuration file altogether.

------
LinuxBender
For functions or secrets? For secrets, ephemeral cache files in a ram disk
that set variables with proper posix permissions that only allow root and the
application to read. The file should be removed when no longer required.

Why? Avoid leaving secrets on a hard drive. Cache them in case our secret
store is not reachable. Avoid logging secrets in auditd by keeping them out of
arguments.

------
verdverm
All three, check out the Viper/Cobra packages for Golang

