Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Export .env with special characters

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
like image 211
Peterhack Avatar asked Apr 16 '19 08:04

Peterhack


People also ask

How do I export an .ENV file?

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.

What characters are allowed in environment variables?

Only uppercase letters, lowercase letters, and underscores from this character set are allowed.

How do you escape special characters in variable bash?

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.


2 Answers

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
like image 98
KamilCuk Avatar answered Sep 20 '22 01:09

KamilCuk


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
like image 41
Kurtis Rader Avatar answered Sep 21 '22 01:09

Kurtis Rader