我有一个 JSON 文件,其中包含以下内容(以及其他属性):
{
"environment": "$USER"
}
jq
我使用如下方式提取该值:
ENVIRONMENT="$(jq -r '.environment' "properties.json")"
我希望 的值为ENVIRONMENT
我的用户名,不是字符串$USER
- 这可能吗?
答案1
选项 1:仅按名称读取变量
bash
允许拥有引用变量的变量,例如:
REF='USER' # or get it from JSON
echo "${!REF}"
# prints current username
所以你可以这样写:
ENVIRONMENT_REF="$(jq -r '.environment' "properties.json")"
ENVIRONMENT="${!ENVIRONMENT_REF}"
JSON 内容:
"environment": "USER"
选项2:全壳扩展
其他选择,也许更好(但是绝对不安全)正在使用eval
:
ENVIRONMENT="$(eval "echo $(jq -r '.environment' "properties.json")")"
请注意,这是不安全并且可以将恶意代码插入到 JSON 文件中。什么恶意代码?我们来看看这个properties.json
文件:
{
"environment": "$(rm some_file)"
}
shell 将eval
使用此代码:
echo $(rm some_file)
...并且指定的文件some_file
将被删除。正如您所看到的,根据在那里输入的命令,您可能会造成非常严重的损坏。
答案2
jq
通过对象提供对其环境的访问$ENV
- 类似于 Perl 的$ENV
哈希或 awk 的ENVIRON
关联数组。因此,例如假设(如接受的答案所建议的)您的properties.json文件看起来像
{
"environment": "USER"
}
那么你可以做
$ environment="$(jq -r '$ENV[.environment]' properties.json)"
$ echo "$environment"
steeldriver
(最好避免 shell 变量使用全部大写)。如果你的文件看起来像
{
"environment": "$USER"
}
包括 shell 扩展$
,那么您可以在删除后使用相同的方法$
:
environment="$(jq -r '$ENV[.environment | sub("^\\$";"")]' properties.json)"
或者,您可以通过外部命令传递简单查找的结果envsubst
:
$ environment="$(jq -r '.environment' properties.json | envsubst)"
$ echo "$environment"
steeldriver
答案3
这只是对 其他答案之一。
在 Linux 终端中,创建一个本地文件夹:
$ mkdir -p ~/unix.se/jq/ && cd ~/unix.se/jq/
创建文件properties.json
:
$ echo '{"environment":"USER"}'>properties.json && cat properties.json
{"environment":"USER"}
附注 - 漂亮的格式jq
:
$ jq '.' properties.json
{
"environment": "USER"
}
使用 JSON key 的值environment
设置新的环境变量并显示其内容:1
$ JQ_USER=$(jq -r '$ENV[.environment]' properties.json) && echo $JQ_USER
tedly
到目前为止一切顺利,但问题是我一直在撒谎。(!) - 文件
properties.json
看起来不正确相当如上所述,因为它前面有一个美元符号USER
,如下所示:
$ echo '{"environment":"$USER"}'>properties.json && cat properties.json
{"environment":"$USER"}
通过摆脱那个令人不安的美元符号,例如用空字符串代替它,我们可以回到已经有效的解决方案:
$ JQ_USER=$(jq -r '$ENV[.environment | sub("\\$";"")]' properties.json)
echo $JQ_USER
tedly
1当我第一次运行此程序时,我收到一条以
jq: error: ENV/0 is not defined at <top-level>
.事实证明$ENV[]
需要1.6版本(或稍后)的jq
.
答案4
一种方法可以如下
ENVIRONMENT=$(printenv $(jq -r '.environment' properties.json |
cut -c2-))