2

I have made the following bash script in order to export values from a specific file named params.env:

#!/bin/bash

SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done

SOURCE=$(dirname ${SOURCE})

export $(cat "${SOURCE}/../params.env" | xargs)

The params.env has the values:

Param1=param1
Param2="Space separated value"

But it successfully exports Param1 but it fails to export Param2.

Do you have any idea how to solve this?

5
  • 1
    If you trust your file to be safely evaluated as code, you could just run set -a (causing all defined variables to be automatically exported), and then source params.env. Commented May 13, 2017 at 23:35
  • (BTW -- are the quotes in the file format a hard requirement? This would be easier without them; while IFS='=' read -r name value; do printf -v "$name" %s "$value"; export "$name"; done would suffice in that case). Commented May 13, 2017 at 23:36
  • Yes because I use it in otder to export enviromental variables het I use them on my Symfony written php application that also run on a cli. Commented May 13, 2017 at 23:41
  • 2
    BTW, as an aside, consider a lowercase variable name to replace SOURCE. All-caps names are used for variables with meaning to the OS or shell; lowercase variable names are reserved for application use and guaranteed not to modify shell behavior. See pubs.opengroup.org/onlinepubs/9699919799/basedefs/…, fourth paragraph. Commented May 13, 2017 at 23:46
  • I usually use this pattern SYMFONY__var_1 for Symfony's enviromental variable. So I use convension Instead of conviguration form parameters. Commented May 13, 2017 at 23:49

2 Answers 2

7

First -- if you trust your file to be safely evaluated as a shell script with your current user's privileges, this could be as simple as:

set -a                           # automatically export all shell variables
source "${SOURCE}/../params.env" # evaluate file as a shell script
set +a                           # turn off automatic export

Otherwise, the answer by mklement0 is appropriate.

Sign up to request clarification or add additional context in comments.

Comments

4

If you trust the input file to only contain syntactically valid shell variable assignments, consider Charles Duffy's simpler set -a-based answer.

Use a while loop that calls export on each name-value pair:

while IFS='=' read -r name value; do
  export "$name=${value//'"'/}"
done < "${SOURCE}/../params.env"

Note: The above simply removes all " instances in the value and therefore assumes that values only have enclosing double quotes, not also (escaped) embedded ones.

If there are embedded " instances, and they're properly escaped as \" :

while IFS='=' read -r name value; do
  # Handle double-quoted ("...") values.
  if [[ $value =~ ^\"(.*)\"$ ]]; then
    # Using `read` without `-r` removes the \ from embedded \<char> sequences.
    IFS= read value <<<"${BASH_REMATCH[1]}"
  fi
  # Define and export the variable.
  export "$name=$value"
done < "${SOURCE}/../params.env"
  • Regex matching operation [[ $value =~ ^\"(.*)\"$ ]] matches a "..." value and, by virtue of enclosing everything in between (.*) in (...), captures that in element 1 of special array variable ${BASH_REMATCH[@]}, in which the results of the matching operation (=~) are stored.

  • Use of read without -r with the contents of the content of the "..." value read (${BASH_REMATCH[1]}) means that all \<char> sequences inside "..." are replaced with just <char>.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.