Hacker News new | past | comments | ask | show | jobs | submit login

    export $(cat .env | xargs)
Agree with the premise but this can be achieved with actual Unix concepts no need for anything else.

The language runtime dotenv projects are banned in my engineering org.




Your example has the downside of making the environment variables sticky, however, so it's not achieving the same thing.


What about:

    source <(cat .env | xargs)
or:

    export $(cat .env | xargs)
And then:

    unset $(cat .env | cut -d= -f1)
?

The last one unsets the environment variables that were set by the first command, ensuring they are not persisted beyond the current shell session.

If you are worried about forgetting to execute it, there are a couple of ways to work around it, depending on your case.


That is kinda the purpose of an environment.


I jump around between multiple projects every day. Sticky environment variables carry risk.


I would suggest using a tool like tmux to partition those projects entirely. Instead of tearing down env and building it back up to switch projects, just re-attach to that tmux session. I treat this stuff as though it’s immutable and try to consciously avoid cross pollination.


That’s reasonable, but my point stands: your original proposal is insufficient to be treated as equivalent.


    env $(cat .env) my-cmd-wanting-dotenv
would, though, wouldn't it?

ETA: the main difference between `env` and `dotenv` seems to be that `env` gets its arguments from the command line, whereas `dotenv` gets its arguments from a file. I think that's a fair difference, but I might also think that perhaps `env` should expand its offering to include some kind of `-f filename` option so that it can focus on the notion of "a configurable sub-environment for a command" and we can avoid subtle distinctions.


Further addition, I haven't investigated dotenv deeply, but I suppose it would be a command that specialises in making sure the contents of .env are just environmental variables that get defined. The `env` command as I wrote it is probably not the sort of thing you want to just trust on a file in a git repo shared with colleagues. Anyway, like my ETA above suggests I'm in two minds about whether env and dotenv should be the same thing with different arguments or not.


Several people, including you, are proposing using env rather than sourcing; is that somehow preferable to something like this?

    (. .env; my-cmd)


See my comment sibling to yours for some concerns with `env $(cat file)`; I would have these and then some with sourcing the file even in a subshell. You can do whatever you want in a shell script which can have effects outside of the subshell.

Another advantage of env is that you can type `man env` and learn something useful; sourcing and subshells via syntax is a little bit harder.

Finally, I think the major point of this branch of the discussion is to explicitly decorate a command with a special environment. Starting up a subshell isn't the same thing. It might have the same effect, but you can see that you're creating a subshell, running a builtin in the subshell, and then running a command in the subshell. It is something of a difference between declarative (dotenv/env) and imperative (sourcing in a subshell) approaches, and inherits all the pros and cons of the imperative approach.

If it works for you, I make no recommendation against it.


Not really, if we are just talking about the "run environment" of a single binary.


What about:

    env $(cat .env) [program]


Has whitespace handling issues... but valiant effort!


When your environment variable values have spaces (e.g. some connection strings) this doesn’t work iirc


I tend to agree, and we do this a lot actually. But it gets a little more complicated if you have several .env files.

Would love to hear more about why dotenv is banned at your org though.


Because I banned it haha. There should not be more than one .env file. Our projects have a .env.example that has any overrides a dev might want to override but this list is kept intentionally very short. Meanwhile .env is noted in gitignore. I absolutely hate seeing an entire application configured with environment variables. Some? Sure, where it makes sense. Most? No, those should be in version control, secrets aside.

I believe in convention over configuration. Most of our apps have hard-coded config, with a concise/short and finite number of things that can be overridden (like 3-4 parameters, tops). Secrets get injected.

I do subscribe to the idea of the 12 factor app, but there is a line that needs to be drawn between env config which is more dynamic and more persistent config that should be baked in to the release.


To add to that, SOME_SECRET env vars should be banned (or at least overridable) in favor of SOME_SECRET_FILE env vars. I usually just put an example of the env vars into the readme or link to the file in the source code handling that directly.


But then the problem is changing configs means building a new release, and needs code push access. Pretty much every config variable has env override in my apps - allows project owner to poke about in web UI without bothering me for changes.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: