Also, if we are going to involve the shell, we could also just make .env a shell fragment and do this:
sh -c '. .env; <cmd>'
There is a way to pass commands to it which are reliably executed, like thisL
sh -c '. .env; "$@"' -- command arg1 arg2 arg3.
The non-option arguments passed to the shell are available as `"$@"`. A command consisting of nothing but `"$@"` basically executes the arguments. We can use `exec`, speaking of which:
I wouldn't follow this approach because if you run `. .env;` you .env gets evaluated as a bash script, not as a configuration file. This means that you can get runtime errors in the .env file, and nobody wants that.
Sourced environment scripts in the Unix environment are standard operating procedure. E.g. for toolchains.
The .env being evaluated as a shell script means that it's in a widely used language, with a widely known syntax. You can look at it and know what it's going to do.
The .env being a data format to some uncommon utility; that's anyone's guess.
For instance, suppose we want a newline character in an environment variable. Does the given "env file" format support that? How?
There is one de-facto standard format: the /proc/<pid>/environ kernel output format on Linux. The variables are null-terminated strings, so it is effectively a binary format. It represents any variable value without requiring quoting mechanisms.
-S is a fairly recently added option to the GNU Coreutils env (possibly inspired by BSD?). I have a window to an Ubuntu 18 VM where it's not available.
You want $(cat .env) quoted, as in "$(cat .env)" so that the content of the file is reliably passed as one argument.
-S will split on whitespace; but it respects quoting, so spaces can be protected. Basically .env has to be prepared with the features of -S in mind. Of which that thing has quite a few: escape sequences like \n, commenting, environment variable substitution.
This will fail with comments. Of course you can script around that as well (I have done so), but it's not bulletproof. It makes sense to have a dedicated tool for the job.
Isn’t the problem with dotenv that it’s not a formal specification? The closest to a specification is the “reference” nodejs implementation. Even across languages that aren’t shell the behaviors differ to some extent. I think also it’s not just comments, there are probably some other edge cases that can’t be parsed as legitimate shell code either.
edit 2: seems that there are expectation around a complex .env unspecified file format I was totally not aware of, I was just merely trying to share the simplest way I've ever found to store and reuse env vars
`env -S "$(cat .env)" <cmd>`
Believe it or not that’s all you need.
> S, --split-string=S process and split S into separate arguments; used to pass multiple arguments on shebang lines
edit: forgot the quotes around shell substitution