选项 1:仅按名称读取变量

选项 1:仅按名称读取变量

我有一个 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-))

相关内容