Qir*_*han 12 bash shell json environment-variables jq
如果我有这样的JSON,
{
"hello1": "world1",
"testk": "testv"
}
Run Code Online (Sandbox Code Playgroud)
我想将这些键值对中的每一个导出为环境变量,如何通过shell脚本来实现?那么,例如,当我在终端上写字时echo $hello1,world1应该打印并且类似地用于其他键值对?注意:上面的JSON存在于一个被调用但$values不在文件中的变量中.
我知道它将通过jq并为此编写一个shell脚本来完成,但它不起作用.
for row in $(echo "${values}" | jq -r '.[]'); do
-jq() {
echo ${row} | jq -r ${1}
}
echo $(_jq '.samplekey')
done
Run Code Online (Sandbox Code Playgroud)
编辑:尝试Turn的答案,我这样做了:
values='{"hello1":"world1","hello1.world1.abc1":"hello2.world2.abc2","testk":"testv"}'
for s in $(echo $values | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" ); do
export $s
done
Run Code Online (Sandbox Code Playgroud)
Tur*_*urn 14
借用这个将JSON转换为key = value对的所有艰苦工作的答案,您可以通过循环jq输出并将export它们放入环境中来实现:
for s in $(echo $values | jq -r "to_entries|map(\"\(.key)=\(.value|tostring)\")|.[]" ); do
export $s
done
Run Code Online (Sandbox Code Playgroud)
使用命令替换$():
# $(jq -r 'keys[] as $k | "export \($k)=\(.[$k])"' file.json)
# echo $testk
testv
Run Code Online (Sandbox Code Playgroud)
编辑:回应此评论
你应该做
$( echo "$values" | jq -r 'keys[] as $k | "export \($k)=\(.[$k])"' )
Run Code Online (Sandbox Code Playgroud)
请注意double周围的引号$values
注意:无法确认这种方法是否存在安全隐患,即用户是否可以操纵json来造成严重破坏。
另一种不使用jq 的方法是使用grep & sed解析json :
for keyval in $(grep -E '": [^\{]' my.json | sed -e 's/: /=/' -e "s/\(\,\)$//"); do
echo "export $keyval"
eval export $keyval
done
Run Code Online (Sandbox Code Playgroud)
解释:
:为=,并删除尾随的,。"key"=value用 eval导出这是一个输出示例,从 AWS 记录集中导出 json 密钥:
导出“名称”="\052.apps.nmanos-cluster-a.devcluster.openshift.com。"
导出“类型”=“A”
导出“HostedZoneId”=“Z67SXBLZRQ7X7T”
导出 "DNSName"="a24070461d50270e-1391692.us-east-1.elb.amazonaws.com。"
导出“EvaluateTargetHealth”=false
现有的答案都没有在 POSIX shell 的值中保留空格。以下行将用于jq获取某些 JSON 的每个键:值并将它们导出为环境变量,并正确转义空格和特殊字符。
2023-01-28:修正更新:
我之前的答案并不适用于所有可能的值,并且可能会导致错误。请改用以下行,它使用 jq 的@sh格式字符串来正确转义 shell 的值。您还必须将后面的所有内容括eval在引号中以保留换行符。我已更新示例 JSON 文件以包含更多用于测试的字符。
现在看来,这个答案是唯一可以处理所有情况的答案。没有循环,只需一行即可导出所有值。缺点是它使用eval,这在理论上是危险的......但是因为整个key=value 现在正在为 shell 进行转义,所以这应该可以安全使用。
新答案(使用这个):
eval "export $(echo "$values" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')"
Run Code Online (Sandbox Code Playgroud)
旧答案(不要使用这个):
eval export $(echo "$values" \
| jq -r 'to_entries|map("\"\(.key)=\(.value|tostring)\"")|.[]' )
Run Code Online (Sandbox Code Playgroud)
编辑感谢@Delthas 指出缺少的“导出”
JSON 文件示例:
bash-5.2$ cat <<'EOJSON' > foo.json
{
"foo_1": "bar 1",
"foo_2": "This ! is ' some @ weird $text { to ( escape \" here",
"foo_3": "this is some \nsample new line\n text to\ntry and escape"
}
EOJSON
Run Code Online (Sandbox Code Playgroud)
示例脚本:
bash-5.2$ cat <<'EOSH' > foo.sh
values="`cat foo.json`"
eval "export $(echo "$values" | jq -r 'to_entries | map("\(.key)=\(.value)") | @sh')"
export
echo "foo_2: $foo_2"
echo "foo_3: $foo_3"
EOSH
Run Code Online (Sandbox Code Playgroud)
运行示例脚本:
bash-5.2$ env -i sh foo.sh
export PWD='/path/to/my/home'
export SHLVL='1'
export foo_1='bar 1'
export foo_2='This ! is '"'"' some @ weird $text { to ( escape " here'
export foo_3='this is some
sample new line
text to
try and escape'
foo_2: This ! is ' some @ weird $text { to ( escape " here
foo_3: this is some
sample new line
text to
try and escape
Run Code Online (Sandbox Code Playgroud)
优点:
缺点:
eval,这被认为是“不安全的”。但是,由于jq转义所有输入,这不太可能导致安全问题(除非jq发现存在无法使用@sh过滤器正确转义数据的错误)。| 归档时间: |
|
| 查看次数: |
13939 次 |
| 最近记录: |