有没有一种方法可以将jq输出到bash脚本的多个变量中?

有没有一种方法可以将jq输出到bash脚本的多个变量中?,bash,environment-variables,export,jq,Bash,Environment Variables,Export,Jq,基本上,我有一个bash脚本,它在某一点上进行API调用,并生成证书和密钥,然后以json格式返回。我通过管道将其传输到jq,可以选择证书或密钥并将其存储在变量中 大概是这样的: CERT=$(API call | jq -r '.certificate') or KEY=$(API call | jq -r '.key') 我想将每个都存储在自己的变量中,但我不能调用两次,因为它将生成一个新的证书/密钥 我知道我可以将这两个值都存储在一个文件中,然后在完成任务后进行操作,但我很好奇jq是否提

基本上,我有一个bash脚本,它在某一点上进行API调用,并生成证书和密钥,然后以json格式返回。我通过管道将其传输到jq,可以选择证书或密钥并将其存储在变量中

大概是这样的:

CERT=$(API call | jq -r '.certificate')
or
KEY=$(API call | jq -r '.key')
我想将每个都存储在自己的变量中,但我不能调用两次,因为它将生成一个新的证书/密钥


我知道我可以将这两个值都存储在一个文件中,然后在完成任务后进行操作,但我很好奇jq是否提供了一种直接的方法来选择性地将每个值存储在自己的变量中?

您可以将原始JSON存储在一个变量中而不是文件中,然后从中提取密钥和证书:

apiResult=$(API call)
cert=$(jq -r '.certificate' <<<"$apiResult")
key=$(jq -r '.key' <<<"$apiResult")

注意:我建议使用小写或混合大小写变量,以避免和许多具有特殊含义的全大写名称发生意外冲突。另外,如果两个值都不包含换行符,则可以轻松使用read:

或:


证书几乎肯定会包含换行符,因此许多人希望序列化该数据,例如,base64对其进行编码。但是您最好使用Gordon Davidson的方法。

除非字符串中有NUL字符,否则不需要多次调用jq或序列化数据

在最简单的情况下,您可以按照以下步骤进行:

{ IFS= read -r certificate
  IFS= read -r key
  echo "certificate=$certificate"
  echo "key=$key"
} < <(API call | jq -r '.certificate, .key')
相反地 如果感兴趣的值可能包含文字NUL值\u0000,那么这个问题似乎有问题,因为bash变量实际上不能包含文字NUL

如果任何感兴趣的值可能包含文字NUL值,那么以下是将原始字符串等价物提取到单独文件中的两种策略:

将JSON输出保存在一个临时文件中,并以明显的方式为每个感兴趣的值调用一次jq-r

设置bash管道,从以下内容开始:

API调用| jq-r'.certificate、.key |@base64`

并继续循环,其中每一行都被解码,例如使用base64-decode或jq的@base64d


如果API调用生成一个非常大的JSON文档,那么第二种策略可能有意义。

假设您创建了一个输出shell命令的程序

$data\u source | jq-r'@sh certificate=\.certificate\nkey=\.key' certificate='证书' 钥匙 然后,你需要做的就是评估它们

eval$data\u source | jq-r'@sh certificate=\.certificate\nkey=\.key' 如果要处理许多变量,可以使用以下方法:

评估$ 数据源| jq-r' {certificate:certificate,key:key}作为$map| $map | keys_unsorted[]作为$shell_var| $shell\u var+@sh=\.[$map[$shell\u var]] ' 你甚至可以使用路径

评估$ 数据源| jq-r' {certificate:[certificate],key:[key]}作为$map| $map | keys_unsorted[]作为$shell_var| $shell\u var+@sh=\getpath$map[$shell\u var] '
证书可能包含文字NUL\u0000字符?在bash中,不能将NULL字符存储在变量中,因此问题似乎假定不是,但是。。。。[使用read的两种解决方案还对空格和反斜杠进行了一些假设。如果需要序列化数据,可能是因为NUL,但是使用bash变量会有问题……Env VAR不能包含NUL,因此您不需要添加限制。
$ { read cert; read key; } << EOF
> $( echo '{"certificate": "foo", "key": "bar"}' | jq -r .certificate,.key )
> EOF
$ echo $cert:$key
foo:bar
{ IFS= read -r certificate
  IFS= read -r key
  echo "certificate=$certificate"
  echo "key=$key"
} < <(API call | jq -r '.certificate, .key')
while IFS= read -r -d $'\0' certificate
do
  IFS= read -r -d $'\0' key
  echo "certificate=$certificate"
  echo "key=$key"
done < <(API call | jq -rj '[.certificate, .key] | join("\u0000")')