JQ Linux JSON解析未知密钥

JQ Linux JSON解析未知密钥

我想构建一个自动化脚本,在 vultr.com 页面上构建一个新的 VPS 服务器。他们还有 API 访问权限,我可以创建它并接收我需要的任何内容。问题是,vultr 发送一个响应,其中包含一个数字作为每个 VPS 服务器的密钥。我使用此命令创建 VPS 并获取服务器的编号:

idofserver=$(curl -H 'API-KEY: "HERE IS MY PRIVATE API KEY"' \
             https://api.vultr.com/v1/server/create \
            --data 'DCID=9' --data 'VPSPLANID=201' --data 'OSID=244' \
            | jq '."SUBID"' | /bin/sed 's/"//g')

它还给了我没有“的数字。所以命令行中的响应看起来像:2342738。并且变量也更改为数字。因为当我输入“echo $idofserver”时,我得到了数字2342738 。

在该行之后,我在循环中执行该命令:

echo "VULRT IS WORKING ID: $idofserver"
response=$(curl -H 'API-KEY: "HERE IS MY PRIVATE API KEY"' \
           https://api.vultr.com/v1/server/list 100>/dev/null)
status=$(echo "$response" | jq '."$idofserver"' | jq '."status"')

它还返回“VULTR IS WORKING ID:2342738”。但它保持在一个完整的循环中,因为它不会将变量 $status 更改为活动状态。 while循环条件为:while [ $status != "active" ]; do

我尝试手动回显响应并jq使用上面 $status 中的命令发送它。但得到的答复是:“无”。我不知道为什么。

VULTR 中的 JSON 响应如下所示:

{"2342738":{"SUBID":"2342738","os":"Debian 9 x64 (stretch)","ram":"1024 MB","disk":"Virtual 25 GB","main_ip":"11.11.11.11","vcpu_count":"1","location":"Frankfurt","DCID":"9","default_password":"=*{#?HHH*!-(","date_created":"2019-04-22 17:49:28","pending_charges":"0.01","status":"active","cost_per_month":"5.00","current_bandwidth_gb":0,"allowed_bandwidth_gb":"1000","netmask_v4":"255.255.0.0","gateway_v4":"11.11.11.11","power_status":"running","server_state":"installingbooting","VPSPLANID":"201","v6_main_ip":"","v6_network_size":"","v6_network":"","v6_networks":[],"label":"","internal_ip":"","kvm_url":"https:\/\/my.vultr.com\/subs\/vps\/novnc\/api.php?data=jhkjhjhkjhkj","auto_backups":"no","tag":"","OSID":"244","APPID":"0","FIREWALLGROUPID":"0"}}

答案1

首先,使用-rwithjq获取原始数据。不要通过以下方式传递输出sed

url='https://api.vultr.com/v1/server'
key='API-KEY: "HERE IS MY PRIVATE API KEY"'

serverid=$( curl -H "$key" "$url/create" \
                --data 'DCID=9' \
                --data 'VPSPLANID=201' \
                --data 'OSID=244' |
            jq -r '.SUBID' )

然后,第二次调用将jq不起作用,因为您在表达式周围使用单引号,这会阻止 shell 变量扩展。然而,那就是不是将 shell 变量传递到jq.

反而:

printf 'VULRT IS WORKING ID: %s\n' "$serverid"

status=$( curl -s -H "$key" "$url/list" 100 |
          jq -r --arg id "$serverid" '.[$id].status' )

使用--arg id "$serverid"将创建一个jq变量,您可以通过 访问其值$id。要将其用作密钥,请使用[$id].

我还根据我自己的个人喜好随意更改了代码中的其他一些内容。

答案2

问题是它'."$idofserver"'是单引号的,因此$idofserver永远不会扩展到它的值 - 您正在寻找一个字面上称为“ $idofserver”的键。

你也永远不需要管道jq | jq。您可以在 jq 程序中将过滤器连接在一起:

.["2342738"].status

您可以修复引用以获得该结果,但更可靠的是,将 id 作为要设置的 jq 变量传递,并完全避免内部引用问题:

jq --arg id "$idofserver" '.[$a].status'

如果可以的话,我建议echo "$response" | jq也避免:直接通过管道,或者使用printf '%s' "$response" | jqor (最好)jq <<<"$response"代替。

相关内容