Show HN: Dotenv, if it is a Unix utility

by gyf304on 4/28/24, 8:25 PMwith 100 comments
by petepeteon 4/28/24, 9:24 PM

I think direnv already does a good job in this space, and it's already available in your package manager.

https://direnv.net/

by tuyiownon 4/29/24, 5:59 AM

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

by grounderon 4/28/24, 10:03 PM

Compare with dotenvx - https://github.com/dotenvx/dotenvx This is my current tool of choice.

by kazinatoron 4/29/24, 5:19 PM

I just remembered. Adding a -f <file> option to the GNU Coreutils env utility has previously been discussed:

https://lists.gnu.org/archive/html/coreutils/2021-10/msg0000...

It came up in the mailing also this March. I saw the posting in my inbox and proposed that a null-terminated format be handled, which is exactly like /proc/<pid>/env:

https://lists.gnu.org/archive/html/coreutils/2024-03/msg0014...

If that feature were available, this becomes

  env -f .env command arg ...

by miohtamaon 4/28/24, 9:40 PM

There is also shdotenv that allows you to load different .env file formats and convert between them, e.g. for UNIX shell.

https://github.com/ko1nksm/shdotenv

by tester457on 4/28/24, 9:26 PM

dotenv started as a ruby library actually. The first implementation inspired the others such as the golang version of the library.

by whalesaladon 4/29/24, 1:58 AM

    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.

by mongolon 4/28/24, 9:53 PM

Would not

sh -c '. .env; echo $MY_VAR'

do the same thing? (I am not in front of a shell at the moment.)

by iDonon 4/29/24, 11:11 AM

Thanks to OP and other posters - various ideas useful in different cases.

The xargs idea made me think of using bash as the parser :

  bash -c "exec -c bash -c 'source $CONFIG/main.bash; env'"
This test .bash file contains multiple source-s of other .bash files, which contain a mix of comments, functions, set and env vars - just the env vars are exported by env. This seems useful e.g. for collating & summarising an environment for docker run -e.

This outputs the env vars to stdout; for the OP's purpose, the output could be sourced :

  envFile=$(mktemp /tmp/env.XXXXXX);

  bash -c "exec -c bash -c 'source $CONFIG/main.bash; env'" > $envFile;

  env $(cat $envFile) sh -c 'echo $API_HOST'
# For Bourne shell, use env -i in place of exec -c :

sh -c "env -i sh -c '. $CONFIG/main.sh; env'" > $envFile

by andy_pppon 4/29/24, 2:00 PM

This looks good and neater than my solution in my .zshrc:

envup() {

  local file=$([ -z "$1" ] && echo ".env" || echo ".env.$1")

  if [ -f $file ]; then
    set -a
    source $file
    set +a
  else
    echo "No $file file found" 1>&2
    return 1
  fi
}

You can also specify `envup development` to load .env.development files should you want. Obviously this will pollute the current shell but for me it is fine.

by belthesaron 4/29/24, 4:59 PM

This is interestingly similar to a little tool I wrote called sops-run [0], which manages encrypted secrets for cli tools using Mozilla’s sops [1]. Biggest upshot is that you can use it more confidently for secrets with encryption at rest. Built it when I was trying out CLI tools that wanted API keys, but I didn’t want to shove them into my profile and accidentally upload them into my dotfiles repository. Do need to finally get back to making this a package, being able to install it with pip(x) would be really nice.

[0] https://github.com/belthesar/sops-run

[1] https://github.com/getsops/sops

by vishvanandaon 4/29/24, 3:17 AM

Doesn’t this already exist as https://www.npmjs.com/package/dotenv-cli ?

by supriyo-biswason 4/29/24, 2:42 AM

I wrote my own some time ago: https://github.com/supriyo-biswas/dotfiles/commit/39585b42c2...

by wodenokotoon 4/29/24, 8:14 AM

Since loading dotenv files happens together with executing code I I have decided to trust my .env files just like I trust the rest of my code not to delete my entire system and therefore I source them.

by KevinMSon 4/29/24, 3:01 AM

I never understood why it had to be a dot file, except for naming it.

by fire_lakeon 4/29/24, 6:40 AM

Does this accept the exact same format (including quotes and whitespace) as a Docker env file? That’s a key feature for me

by prmoustacheon 4/29/24, 6:52 AM

I don't understand what more it does than sourcing a file on your shell would? Anyone can explain?

by kzrdudeon 4/28/24, 11:42 PM

This idea seems to be cloned everywhere now, so something is causing the popularity

by bitwizeon 4/29/24, 5:57 AM

C? Y u no Rust?