Concatenate string after grabbing environment variable

I’m trying to concatenate a string with a variable which is in .env file. My .env is this:

API_URL=http://localhost:3030
NODE_ENV=development

And here is my code:

[ ! -f .env ] || export $(grep -v '^#' .env | xargs)

URL="${API_URL}/health"

echo $URL

I expect this to print http://localhost:3030/health. But it prints /healthlocalhost:3030. What am I missing?

Thanks.

Asked By: sundowatch

||

The issue is that your .env file has Windows (CRLF) line endings instead of the default Unix style LF. That means you end up with a carriage return between the exported variable and the appended text.

I’d strongly recommend fixing the problem at source by configuring vscode to use the correct endings for the OS – however if you must use Windows endings then I’d suggest sourcing the file and marking all its variables for export like this:

if [[ -r .env ]]; then
  set -o allexport
  . <(sed 's/r$//' .env)
  set +o allexport
fi

rather than trying to manipulate the file with grep and xargs.

Answered By: steeldriver

Adding to @steeldriver‘s mindful answer …

Since you’re using the Bash shell, you could use its RegEx matching capability and its parameter expansion using the C-style escape sequence for $'r' to match the r at the end of the lines while reading file lines in a shell loop like this:

while IFS= read -r line; do
  [[ "$line" =~ ^# ]] || export "${line//$'r'}"
done <"file"

… and you could use in your code snippet like this:

[ ! -f .env ] || while IFS= read -r line; do [[ "$line" =~ ^# ]] || export "${line//$'r'}"; done <".env"

All shell builtin and pure Bash.

Notice that unlike the answer by @steeldriver, my answer has the caveat of including, (in the exported variable’s value), quotes around the variable assignment string if there were any like var1="string" or var2='string' and although you can remedy that by extending the parameter substitution pattern from "${line//$'r'}" to "${line//[$'r'|"|']}", you need to keep in mind that this remedy will remove those quotes inside the variable assignment string as well and not just around it … There might be other eval and alike workarounds that I personally feel not safe enough to recommend so skipping those.

Answered By: Raffa