在命令行中使用变量时出现 jq 错误

在命令行中使用变量时出现 jq 错误

我正在使用 jq 通过脚本获取 tag_name 索引:

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

您的 shell 变量GITHUB_TOKEN必须在脚本环境中设置。您当前正在调用 shell 中设置它,然后运行脚本:

GITHUB_TOKEN=sometoken && ./yourscript

GITHUB_TOKEN如果分配成功(即,如果GITHUB_TOKEN不是只读变量),则会设置并运行您的脚本。但是,该变量在脚本中看不到。为此,您必须使用该变量将变量转换为环境变量export GITHUB_TOKEN,或者像这样启动脚本:

GITHUB_TOKEN=sometoken ./yourscript

GITHUB_TOKEN...它在脚本中设置 的值,但不在调用环境中设置。

由于您的脚本中没有正确的值GITHUB_TOKEN,因此 Github 向您提供了以下 JSON 文档作为响应:

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

然后你的jq表达式尝试tag_name细绳 Bad credentials,这显然是行不通的。

请注意,由于 Github 存储库是公共的,因此调用给定的 REST API 端点实际上不需要身份验证(如果我理解正确的话)。


关于您的表达式的另一个评论jq:该jq实用程序有一种方法允许您将数据导入到不依赖于注入 shell 字符串的表达式中。这对您来说使用起来会更安全,因为它可以确保值被正确编码并且不会意外地被评估为表达式:

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

请注意,这$tagname是一个内部jq变量,而不是 shell 变量。

更短的变体(几乎总是不需要将数组中的内容提取到数组中,如[.[].tag_name]):

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

相关内容