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

먼저 -rwith 를 사용하여 jq원본 데이터를 가져옵니다. 다음을 통해 출력을 전달하지 마십시오 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그런 다음 표현식 주위에 작은따옴표를 사용하여 쉘 변수 확장을 방지하므로 두 번째 호출이 작동하지 않습니다. 그러나 그것은아니요셸 변수를 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" | jq(바람직하게는) or를 jq <<<"$response"대신 사용합니다.

관련 정보