if [ ! -f .env ] | |
then | |
export $(cat .env | xargs) | |
fi |
[ ! -f .env ] || export $(sed 's/#.*//g' .env | xargs)Update:
TEXT="abc#def"
not work as expected, so just replace line begin with #.[ ! -f .env ] || export $(grep -v '^#' .env | xargs)
This one works for django .env
this works for me
#!/usr/bin/env bash
. .env
For those using sed to rewrite their .env files before evaluation by bash, for example the solution suggested by @kolypto in https://gist.github.com/mihow/9c7f559807069a03e302605691f85572?permalink_comment_id=3625310#gistcomment-3625310
I ran into another case that hadn't been considered: Windows line endings "\r\n". I'm now using:
set -o allexport # enable all variable definitions to be exported
source <(sed -e "s/\r//" -e '/^#/d;/^\s*$/d' -e "s/'/'\\\''/g" -e "s/=\(.*\)/=\"\1\"/g" "${ENV_FILE}")
set +o allexport
The cleanest solution I found for this was using
allexport
andsource
like thisset -o allexport source .env set +o allexportThis was by far the best solution here for me, removed all the complexity around certain chars, spaces comments etc. Just needed a tweak on formatting to prevent others being tripped up, should be:
set -o allexport
source .env
set +o allexportFrom
man set
:-o option This option is supported if the system supports the User Portability Utilities op‐ tion. It shall set various options, many of which shall be equivalent to the single option letters. The following values of option shall be supported: allexport Equivalent to -a.
So this is the same as
set -a source .env set +a
Worked for me
The above worked fine for me, but thought I'd share the solution I went with:
https://stackoverflow.com/a/30969768/179329set -o allexport; source .env; set +o allexport
As @richarddewit pointed out above, -a
/+a
can be used in place of -o allexport
to be more concise (thanks!).
I now use the following simple line to source .env files into my scripts...
set -a; source .env; set +a
export $(awk -F= '{output=output" "$1"="$2} END {print output}' aaa.env)
[ ! -f .env ] || export $(grep -v '^#' .env | xargs)
Sweet, works like a charm for me, thanks.
oh-my-zsh users can also activate the
dotenv
plugin.
thank you this was better
I had troubles with a (Docker) setup where environment variables had spaces in their value without quotes and I needed to get the container's env. vars. in a script called during the container execution/runtime.
I ended getting the variables in the entrypoint, exporting them to a file and them reading them when needed.
# In entrypoint
export -pn \
| grep "=" \
| grep -v -e PATH -e PWD -e OLDPWD \
| cut -d ' ' -f 3- \
> /docker-container.env
The export
command fixes issues with missing quotes, avoiding errors where the shell interpreter tries to execute parts of the variable value as commands.
# In script
set -o allexport
. /docker-container.env
set +o allexport
(I had to use /bin/sh
so not using source file
but . file
)
Posix compliant version built around set
, [ ]
and .
Many thanks to the prior posters who brought up set -o a
and set -a
/ set +a
This snippet will source a dotenv file, exporting the values into the environment. If allexport
is already set, it leaves it set, otherwise it sets, reads, and unsets.
if [ -z "${-%%*a*}" ]; then
set -a
. ./.env
set +a
else
. ./.env
fi
double brackets [[
, source
, setopt
are not available in posix. Nor is the test [[ -o a ]]
to check for set options. And we need to quote our comparison strings to deal with empty vars.
The code to check if an option is set is a bit of a pain. It could be a case statement or a grep on set -o
like set -o | grep allexport | grep -q yes
, but blech. Instead I've used parameter expansion with pattern matching to remove a maximum match from the $-
variable containing a single line of the set options.
${-%%*a*}
uses %%
parameter expansion to remove the longest suffix matching the pattern *a*
. If $-
contains a
then this expansion produces and empty string which we can test with -z or -n.
subtle bug if no options are set, so the comparison "$-" = "${-%%a*}"
will check that the expansion changed the string. allexport
is set if the two strings differ. And even % will work as we don't need a maximal match and can remove the leading *
from our pattern match.
if [ "$-" = "${-%a*}" ]; then
# allexport is not set
set -a
. ./.env
set +a
else
. ./.env
fi
When the values have newline chars \n
, spaces or quotes, it can get messy.
After a lot of trial and error, I ended up with a variation of what @bergkvist proposed in https://gist.github.com/mihow/9c7f559807069a03e302605691f85572?permalink_comment_id=4245050#gistcomment-4245050 (thank you very much!).
ENV_VARS="$(cat .env | awk '!/^\s*#/' | awk '!/^\s*$/')"
eval "$(
printf '%s\n' "$ENV_VARS" | while IFS='' read -r line; do
key=$(printf '%s\n' "$line"| sed 's/"/\\"/g' | cut -d '=' -f 1)
value=$(printf '%s\n' "$line" | cut -d '=' -f 2- | sed 's/"/\\\"/g')
printf '%s\n' "export $key=\"$value\""
done
)"
env $(cat .env)
this does not work for me but this one works
env $(cat .env|xargs) CMD
my .env has some special value such as FOO='VPTO&wH7$^3ZHZX$o$udY4&i'
@NatoBoram
From
man set
:So this is the same as