Bash
在命令行中使用變數時出現 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 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