명령줄에서 변수를 사용할 때 jq 오류가 발생했습니다.

명령줄에서 변수를 사용할 때 jq 오류가 발생했습니다.

스크립트를 통해 tag_name 인덱스를 가져오기 위해 jq를 사용하고 있습니다.

curl \
 https://api.github.com/repos/checkstyle/checkstyle/releases \
 -H "Authorization: token $GITHUB_TOKEN" \
 -o /var/tmp/cs-releases.json

TARGET_RELEASE_NUM=$1
TARGET_RELEASE_INDEX=$(cat /var/tmp/cs-releases.json | \
    jq -r "[.[].tag_name] | to_entries | .[] | \
    select(.value==\"checkstyle-${TARGET_RELEASE_NUM}\") | .key")
echo TARGET_RELEASE_INDEX="$TARGET_RELEASE_INDEX"

$GITHUB_TOKEN을 하드코딩된 값으로 사용하는 경우에만(스크립트에서 직접) 예상한 결과를 얻지만 $GITHUB_TOKEN을 명령줄 변수로 사용하면 다음과 같은 출력이 나타납니다.

jq: error (at <stdin>:4): Cannot index string with string "tag_name"

다음을 사용할 때 이 오류가 발생합니다.

rahul@rk7:~/Desktop/opensource/checkstyle$ GITHUB_TOKEN=ghp_xxxx && ./.ci/update-github-page.sh 10.1

잘 작동합니다.

curl \
 https://api.github.com/repos/checkstyle/checkstyle/releases \
 -H "Authorization: token ghp_xxxx" \
 -o /var/tmp/cs-releases.json

TARGET_RELEASE_NUM=$1
TARGET_RELEASE_INDEX=$(cat /var/tmp/cs-releases.json | \
    jq -r "[.[].tag_name] | to_entries | .[] | \
    select(.value==\"checkstyle-${TARGET_RELEASE_NUM}\") | .key")
echo TARGET_RELEASE_INDEX="$TARGET_RELEASE_INDEX"

답변1

쉘 변수는 GITHUB_TOKEN스크립트 환경에서 설정되어야 합니다. 현재 호출 셸에서 설정한 다음 스크립트를 실행하고 있습니다.

GITHUB_TOKEN=sometoken && ./yourscript

GITHUB_TOKEN할당이 성공하면(즉, GITHUB_TOKEN읽기 전용 변수가 아닌 경우) 스크립트가 설정되고 실행됩니다. 그러나 변수는 스크립트에 표시되지 않습니다. 이렇게 하려면 변수를 사용하여 환경 변수로 변환 export GITHUB_TOKEN하거나 다음과 같이 스크립트를 시작해야 합니다.

GITHUB_TOKEN=sometoken ./yourscript

GITHUB_TOKEN...스크립트에 설정하는 값이지만 호출 환경에는 설정하지 않습니다.

스크립트에 올바른 값이 없기 때문에 GITHUB_TOKENGithub는 이에 대한 응답으로 다음 JSON 문서를 제공합니다.

{
  "message": "Bad credentials",
  "documentation_url": "https://docs.github.com/rest"
}

그러면 당신의 표정은 다음과 같이 jq바뀌려고 합니다 .tag_name Bad credentials, 분명히 작동하지 않습니다.

Github 저장소는 공개되어 있으므로 지정된 REST API 엔드포인트를 호출하는 데는 실제로 인증이 필요하지 않습니다(제가 올바르게 이해한 경우).


표현식에 대한 또 다른 설명 jq: jq유틸리티에는 쉘 문자열 삽입에 의존하지 않는 표현식으로 데이터를 가져올 수 있는 방법이 있습니다. 이는 값이 올바르게 인코딩되고 실수로 표현식으로 평가되지 않도록 보장하므로 사용하는 것이 더 안전합니다.

jq -r --arg tagname "checkstyle-$TARGET_RELEASE_NUM" '
    [.[].tag_name] | to_entries[] |
    select( .value == $tagname ).key' /var/tmp/cs-releases.json

이는 쉘 변수가 아닌 $tagname내부 변수입니다 .jq

더 짧은 변형(거의 항상 배열의 내용을 배열로 추출하지 않음, 예: [.[].tag_name]):

jq -r --arg tagname "checkstyle-$TARGET_RELEASE_NUM" '
    to_entries[] | select(.value.tag_name == $tagname).key' /var/tmp/cs-releases.json

관련 정보