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
Compare with dotenvx - https://github.com/dotenvx/dotenvx This is my current tool of choice.
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 ...
There is also shdotenv that allows you to load different .env file formats and convert between them, e.g. for UNIX shell.
dotenv started as a ruby library actually. The first implementation inspired the others such as the golang version of the library.
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.
Would not
sh -c '. .env; echo $MY_VAR'
do the same thing? (I am not in front of a shell at the moment.)
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
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.
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.
Doesn’t this already exist as https://www.npmjs.com/package/dotenv-cli ?
I wrote my own some time ago: https://github.com/supriyo-biswas/dotfiles/commit/39585b42c2...
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.
I never understood why it had to be a dot file, except for naming it.
Does this accept the exact same format (including quotes and whitespace) as a Docker env file? That’s a key feature for me
I don't understand what more it does than sourcing a file on your shell would? Anyone can explain?
This idea seems to be cloned everywhere now, so something is causing the popularity
C? Y u no Rust?
I think direnv already does a good job in this space, and it's already available in your package manager.
https://direnv.net/