I am using set -o allexport; source .env; set +o allexport
to export all variables from a .env file. Unfortunately, one variable contains )
for which reason it results in a syntax error. Is there a solution to this with the above command? I know it would be possible setting it in parentheses, but the .env is somewhat autogenerated without parentheses.
Dotenv looks like this for example:
username=test
password=*fdas_dfar+)mbn
To export a environment variable you run the export command while setting the variable. We can view a complete list of exported environment variables by running the export command without any arguments. To view all exported variables in the current shell you use the -p flag with export.
Only uppercase letters, lowercase letters, and underscores from this character set are allowed.
Bash escape character is defined by non-quoted backslash (\). It preserves the literal value of the character followed by this symbol. Normally, $ symbol is used in bash to represent any defined variable.
source .env
source
is a shell command and the .env
file is parsed as shell file. You need to quote your strings, just as you would in shell.
username=test
password='*fdas_dfar+)mbn'
What is good about it, you can run all shell commands from such file:
username=$(echo test)
password='*fdas_dfar+)mbn'
Or you can write your own parser, ex:
while IFS='=' read -r name value; do
if [ -z "$value" -o -z "$name" ]; then
echo "Error - unparsable line!" >&2
exit 1
fi
# add quotes around `'`
value=$(<<<"$value" sed "s/'/'\''/g")
# set the variable value using bash special builtin
printf -v "$name" "%s" "$value"
done <.env
If you want to be able to source .env
then it needs to be valid shell syntax. That means quoting values that contain shell metachars like )
. If that isn't possible because the file also needs to be read by other programs that can't handle the quoting then you will need to read and parse it one line at a time. Do not use eval
as suggested in the older answer. The eval
command almost always causes more problems than it solves. I prefer this approach over using the IFS trick because IFS is itself inherently dangerous and should always be set to IFS=$'\n'
at the top of every script and not subsequently changed:
while read -r line
do
# Insert appropriate checks for malformed input or comments here.
key="${line%%=*}"
val="${line#*=}"
export "$key"="$val"
done < .env
But if you know the input is well formed and you like living dangerously then this also works fine:
while IFS='=' read -r key val
do
export "$key"="$val"
done < .env
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With