Exporting JSON to environment variables

51,029

Solution 1

Borrowing from this answer which does all of the hard work of turning the JSON into key=value pairs, you could get these into the environment by looping over the jq output and exporting them:

for s in $(echo $values | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" ); do
    export $s
done

If the variables being loaded contain embedded whitespace, this is also reasonable, if slightly more complex:

while read -rd $'' line
do
    export "$line"
done < <(jq -r <<<"$values" \
         'to_entries|map("\(.key)=\(.value)\u0000")[]')

Solution 2

Using command substitution $() :

# $(jq -r 'keys[] as $k | "export \($k)=\(.[$k])"' file.json)
# echo $testk
testv

Edit : Responding to this comment

You should do

$( echo "$values" | jq -r 'keys[] as $k | "export \($k)=\(.[$k])"' )

Just mind the double quotes around $values

Note: Couldn't confirm if there is security implication to this approach, that is if the user could manipulate the json to wreak havoc.

Solution 3

Another way, without using jq, is to parse the json with grep & sed:

for keyval in $(grep -E '": [^\{]' my.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
    echo "export $keyval"
    eval export $keyval
done

Explanation:

  • First, grep will filter all "key" : value pairs (value can be "string", number, or boolean).
  • Then, sed will replace : with =, and remove trailing ,.
  • Lastly, exporting the "key"=value with eval

Here's an output example, exporting json keys, from an AWS record-set:

export "Name"="\052.apps.nmanos-cluster-a.devcluster.openshift.com."

export "Type"="A"

export "HostedZoneId"="Z67SXBLZRQ7X7T"

export "DNSName"="a24070461d50270e-1391692.us-east-1.elb.amazonaws.com."

export "EvaluateTargetHealth"=false

Solution 4

None of the existing answers preserve whitespace in the values in a POSIX shell. To do that, try:

eval $(echo "$values" | jq -r 'to_entries|map("\"\(.key)=\(.value|tostring)\"")|.[]' )

Example:

$ cat <<'EOJSON' > foo.json
{
 "foo_1": "bar 1",
 "foo_2": "bar 2"
}
EOJSON

$ cat <<'EOSH' > foo.sh
values="`cat foo.json`"
eval export $(echo "$values" | jq -r 'to_entries|map("\"\(.key)=\(.value|tostring)\"")|.[]' )
export
echo "foo_2: $foo_2"
EOSH

$ env -i sh foo.sh
export PWD='/home/vagrant'
export foo_1='bar 1'
export foo_2='bar 2'
foo_2: bar 2

Pros:

  • no need for Bash
  • preserves whitespace in values
  • no loops

Cons:

  • uses eval, which I'm pretty sure is not "safe"

Solution 5

The approach illustrated by the following shell script avoids most (but not all) problems with special characters:

#!/bin/bash

function json2keyvalue {
   cat<<EOF | jq -r 'to_entries|map("\(.key)\t\(.value|tostring)")[]'
{
    "hello1": "world1",
    "testk": "testv"
}
EOF
}

while IFS=$'\t' read -r key value
do
    export "$key"="$value"
done < <(json2keyvalue)

echo hello1="$hello1"
echo testk="$testk"

Note that the above assumes that there are no tabs in the keys themselves.

Share:
51,029
Qirohchan
Author by

Qirohchan

Updated on July 09, 2022

Comments

  • Qirohchan
    Qirohchan almost 2 years

    If I have a JSON like this,

    {
        "hello1": "world1",
        "testk": "testv"
    }
    

    And I want to export each of these key-value pairs as environment variables, how to do it via shell script? So for example, when I write on the terminal, echo $hello1, world1 should be printed and similarly for other key-value pairs? Note: The above JSON is present in a variable called $values and not in a file.

    I know it will be done via jq and written a shell script for this, but it doesn't work.

    for row in $(echo "${values}" | jq -r '.[]'); do
        -jq() {
            echo ${row} | jq -r ${1}
        }
        echo $(_jq '.samplekey')
    done