Bash

在命令行中使用變數時出現 jq 錯誤

  • August 21, 2022

我正在使用 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 as a hardcoded value (directly in the script) but when I use $ 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"

您的 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表達式嘗試從stringtag_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

引用自:https://unix.stackexchange.com/questions/714351