4 ms·
Please just see this `env -S "$(cat .env)" <cmd>` Believe it or not that’s all you need. > S, --split-string=S process and split S into separat
by tuyiown 2y ago
Please just see this
`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
- kazinator 2y agoThis is now syntax that requires processing by the shell. The nice thing about utilities like env and dotenv is that they can be easily exec-ed: execl("/usr/bin/dotenv", "/usr/bin/dotenv", "command", "arg", (char *) 0); -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.
- kazinator 2y agoAlso, 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: sh -c '. .env; exec "$@"' -- command arg1 arg2 arg3. What I'm getting at is that this form is fairly easily exec-able; execl("/bin/sh", "/bin/sh", ". .env; exec \"$@\"", "--", "command", "arg1", "arg2", "arg3", (char *) 0); The command and arguments can be arbitrary strings, not subject to any shell mangling.
- cholindo 2y agoI 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.
- kazinator 2y agoSourced 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.
- ibotty 2y agoThis 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.
- SOLAR_FIELDS 2y agoIsn’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.
- deleted 2y ago[deleted]
- tuyiown 2y agoedit 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
- userb 2y agoWhat is the difference with or without "-S". 'env $(cat .env) <cmd>' still work?
- chasil 2y agoksh/bash can abbreviate $(cat x) to $(<x) although this syntax is not in POSIX (and it should be).