5 ms·
I hope I don't get downvoted, but I think the OP has a point. Command line arguments will do, and perhaps even be better. Why are there so many harsh comments
by sedeki 6y ago
I hope I don't get downvoted, but I think the OP has a point. Command line arguments will do, and perhaps even be better.
Why are there so many harsh comments about this post?
- mdpopescu 6y agoThere are a lot of use cases. For example, I have 17 applications running on a system that need a connection string. When I need to change that connection string, I can 1) change 17 config files; 2) change 17 shortcuts containing command-line arguments; 3) change one env variable.
- q3k 6y ago> I can 1) change 17 config files; 2) change 17 shortcuts containing command-line arguments; 3) change one env variable. This seems like forcing the application to take the burden of your configuration system having shortcomings (like not being able to freely convert from a single source of truth into multiple generated files/command lines/...).
- zabzonk 6y agoOr change ONE file that contains the connection string.
- snidane 6y agoEnv vars are a built-in for key-value command line args. Why introduce some custom convoluted way into your app for kv args instead of this standardised approach. I can understand why some heavily used cli app would support a custom parameter pattern, eg. for ergonomics, but for majority of apps running as deployed services and not cli apps invoked 100 times a day, I don't see a reason to not use env args. I can run the following and introduce exactly zero parsing boilerplate into my app or invoking scripts. port=12345 color=green ./myapp.py Also - some apps have to be configured from file, others on the command line. Which parameter parsing library even supports that? Env vars support this out of the box.
- zokier 6y agoEnviron isn't actually key-value, it's only convention that applications (/libraries) parse it in the name=value form. But the underlying mechanism is similar to cmdline: array of pointers to strings. You could parse cmdline same way if you'd want.
- yrro 6y agoIt's an exceedingly strong convention. I'd be genuinely curious to learn of non-malways uses for entries within the environment block that don't fit the standard name=value pattern.
- josephcsible 6y agoDon't POSIX and portable C both require key=value? If so, isn't that more than just convention?
- zokier 6y agoRighto, I was considering Linux only, I don't personally care much for POSIX. I don't think ISO C standard sets any strong requirements. But yes, if you want maximum portability then you probably should be pretty conservative with environment.
- spc476 6y agoI don't know about POSIX, but C doesn't mandate an implementation. The C Standard says about getenv(): Quote: The getenv function searches an environment list, provided by the host environment, for a string that matches the string pointed to by name. The set of environment names and the method for altering the environment list are implementation-defined. The implementation shall behave as if no library function calls the getenv function. Returns The getenv function returns a pointer to a string associated with the matched list member. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the getenv function. If the specified name cannot be found, a null pointer is returned. End quote. The takeaway from me is that yes, environments do define a key/value store of some sort, but how they're implemented isn't stated. It can be an array of strings in "key=value" format stored in RAM, but it could just as well be a hash table stored in ROM.
- q3k 6y agoI agree. I also prefer command line arguments (or even config files) instead of environment variables, in all three cases: when developing software that others run, running software that others have developed, and running software I've developed. In addition to what's said in the post, environment variables have one more significant, practical shortcoming: if an application 'foo' takes a FOO_LOGDIR (which defaults to /var/log/foo if unset) and you accidentally slip it a FOO_LODGIR=/run/log/foo - it will silently accept and ignore it, while you will be scratching your head why is the logging not behaving as expected, until you discover the typo. Naturally, 'foo' could ensure no FOO_* with unknown names are set. But I've yet to see an application like this in practice, while nearly every single flag parsing library out there immediately errors out on unknown flags.
- zokier 6y agoIn typical Linux setups, cmdline is world-readable, but environ is not. So you never should put secrets in cmdline, but they are ok to be in environ. And that is pretty much the only difference between the two.
- henvic 6y agoUnfortunately many people here have a bad attitude thinking they know everything. His point is completely valid. I myself always disliked this kinda recently use of environment variables for configuration – that likely has the 12-factor methodology to blame for its acceptance.
- alerighi 6y agoCommand line parameters should be used for things that change frequently, not for configuration variables. You don't want to pass 20 command line parameters every time you invoke a program. You rather want to set your environment variables one time in your shell initialization script (.bashrc, .zshrc, whatever). You can say there are the configuration files, and sure a complex program should have its configuration file. The problem of configuration files is that they all use a different syntax that you have to learn, you have to write them, back them up, copy around, etc. Also you don't have a simple way of overriding a configuration file parameter for one invocation of the program, that isn't modifying the configuration file. With environment variables is simple: set them before executing the program. Last thing is that environment variables aren't specific to a particular program: they are readable by every program executed in that shell. A configuration file cannot be easily shared, since one program can change its format to make it no longer backwards compatible, so you can't rely on reading other program configuration files. While you can with environment variables.