简体   繁体   English

将 JSON 导出到环境变量

[英]Exporting JSON to environment variables

If I have a JSON like this,如果我有这样的 JSON,

{
    "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?我想将这些键值对中的每一个导出为环境变量,如何通过 shell 脚本来实现? So for example, when I write on the terminal, echo $hello1 , world1 should be printed and similarly for other key-value pairs?因此,例如,当我在终端上写入时, echo $hello1world1应该被打印出来,其他键值对也类似吗? Note: The above JSON is present in a variable called $values and not in a file.注意:上面的 JSON 存在于名为$values的变量中,而不是文件中。

I know it will be done via jq and written a shell script for this, but it doesn't work.我知道它将通过jq完成并为此编写了一个 shell 脚本,但它不起作用。

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

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 export ing them:借用这个答案,它完成了将 JSON 转换为键=值对的所有艰苦工作,您可以通过循环jq输出并将它们export到环境中:

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")[]')

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请注意$values周围的double引号

Note: Couldn't confirm if there is security implication to this approach, that is if the user could manipulate the json to wreak havoc.注意:无法确认这种方法是否存在安全隐患,即用户是否可以操纵json来造成严重破坏。

Another way, without using jq , is to parse the json with grep & sed :另一种不使用jq 的方法是使用grep & sed解析json:

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 ).首先,grep 将过滤所有"key" : value对(值可以是"string"numberboolean )。
  • Then, sed will replace : with = , and remove trailing , .然后, sed 将替换:= ,并删除尾随的,
  • Lastly, exporting the "key"=value with eval最后,使用 eval 导出"key"=value

Here's an output example, exporting json keys, from an AWS record-set:这是一个输出示例,从 AWS 记录集中导出 json 密钥:

export "Name"="\\052.apps.nmanos-cluster-a.devcluster.openshift.com."导出“名称”="\\052.apps.nmanos-cluster-a.devcluster.openshift.com。"

export "Type"="A"导出“类型”=“A”

export "HostedZoneId"="Z67SXBLZRQ7X7T"导出“HostedZoneId”=“Z67SXBLZRQ7X7T”

export "DNSName"="a24070461d50270e-1391692.us-east-1.elb.amazonaws.com."导出“DNSName”="a24070461d50270e-1391692.us-east-1.elb.amazonaws.com。"

export "EvaluateTargetHealth"=false导出“EvaluateTargetHealth”=false

None of the existing answers preserve whitespace in the values in a POSIX shell. To do that, try:现有答案均未在 POSIX shell 的值中保留空格。为此,请尝试:

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不需要 Bash
  • preserves whitespace in values在值中保留空格
  • no loops没有循环

Cons:缺点:

  • uses eval , which I'm pretty sure is not "safe"使用eval ,我很确定这不是“安全的”

The approach illustrated by the following shell script avoids most (but not all) problems with special characters:以下 shell 脚本说明的方法避免了大多数(但不是全部)特殊字符问题:

#!/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.请注意,以上假设键本身没有选项卡。

jtc解决方案:

export $(<file.json jtc -w'[:]<>a:<L>k' -qqT'"{L}={}"')

I've come up with a solution (here in bash):我想出了一个解决方案(在 bash 中):

function source_json_as_environ() {
  eval "$(jq -r '
  def replace_dot:
    . | gsub("\\."; "_");
  def trim_spaces:
    . | gsub("^[ \t]+|[ \t]+$"; "");
  to_entries|map(
    "export \(.key|trim_spaces|replace_dot)="
    + "\(.value|tostring|trim_spaces|@sh)"
    )|.[]' $@)"
}

And you can use it like this:你可以这样使用它:

$ source_json_as_environ values.json

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM