コマンドラインで変数を使用すると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エンドポイントを呼び出すために実際に認証は必要ありません(私が正しく理解した場合)。


式の別の説明jqjqユーティリティには、シェル文字列の挿入に依存しない式にデータをインポートする方法があります。これは、値が正しくエンコードされ、誤って式として評価されないようにするため、使用する方が安全です。

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

おすすめ記事