【问题标题】:How to use variable with jq cmd in shell如何在shell中使用带有jq命令的变量
【发布时间】:2021-09-14 14:22:33
【问题描述】:

我遇到了以下命令的问题。我需要使用变量,但它返回 null 而当我硬编码它的值时,它返回正确的响应。 谁能帮我写这个命令的正确方法是什么? 我的意图是提取作为变量传递的相应键的值?

temp1="{    \"SSM_DEV_SECRET_KEY\": \"Smkfnkhnb48dh\",     \"SSM_DEV_GRAPH_DB\": \"Prod=bolt://neo4j:Grt56@atc.preprod.test.com:7687\",  \"SSM_DEV_RDS_DB\": \"sqlite:////var/local/ecosystem_dashboard/config.db\",     \"SSM_DEV_SUPPERUSER_USERNAME\": \"admin\",    \"SSM_DEV_SUPPERUSER_PASSWORD\": \"9dW6JE8@KH9qiO006\"   }"

var_name=SSM_DEV_SECRET_KEY
echo $temp1 | jq -r '.SSM_DEV_SECRET_KEY'  <----- return Smkfnkhnb48dh // output
echo $temp1 | jq -r '."$var_name"'  <---- return null
echo $temp1 | jq -r --arg var_name "$var_name" '."$var_name"'  <---- return null , alternative way

更新:我正在添加我尝试使用上述修复的实际部分。我的意图是首先读取所有以 SSM_DEV_... 开头的值,然后从 aws 获取原始值而不是替换它。一对密钥看起来像这样 --> SECRET_KEY=$ SSM_DEV_SECRET_KEY

temp0="dev"
temp1="DEV"
result1=$(aws secretsmanager get-secret-value --secret-id "xxx-secret-$temp0" | jq '.SecretString')
while IFS= read -r line; do
    if [[ "$line" == *"=\$SSM_$temp1"* ]]; then
        before=${line%%"="*}
        after=${line#*"="}
        var_name="${after:1}"
        jq -r --arg var_name "$var_name" '.[$var_name]' <<< "$result1"
    fi
done < sample_file.txt

修复:我已经解决了我的回车符问题。 下面的cmd帮帮我:

var_name=`echo ${after:1} | tr -d '\r'`
jq -r --arg var_name "$var_name" '.[$var_name]' <<< "$result1"

【问题讨论】:

标签: shell jq


【解决方案1】:

您需要使用Generic Object Index (.[$var_name]) 让 知道变量应该被视为键

命令应该是这样的:

jq -r --arg var_name "$var_name" '.[$var_name]' <<< "$temp1"

Wich 将输出:

Smkfnkhnb48dh

注意:&lt;&lt;&lt; "$temp1" 而不是 echo

【讨论】:

  • 谢谢。您的回答对我有用。我想知道一件事,当我像下面这样使用它时它不起作用,然后给我错误“q: error (at :1): Cannot index string with string "SSM_DEV_SECRET_KEY temp0="dev" result1= $(aws secretsmanager get-secret-value --secret-id "ttt-secret-$temp0" | jq '.SecretString') while IFS= read -r line;如果 [[ "$line" == "=\$SSM_$temp1" ]];然后 before=${line%%"="} after=${line#"="} var_name="${after:1}" jq -r --arg var_name "$var_name" '.[$var_name]'
  • 抱歉,这样的代码不可读。如果这是原始问题的一部分,请将其添加到您的问题中,否则您可能想问另一个问题!
  • 这听起来像是与当前问题范围无关的问题。我建议 upvotingaccepting 任何有助于解决此问题的答案。然后再问一个你仔细解释新问题的问题。
【解决方案2】:

我们看下面的语句:

echo $temp1 | jq -r '."$var_name"'  <---- return null

您的问题实际上是 shell 引用而不是 jq。单引号告诉外壳程序不要在其他事情中进行插值(进行变量替换)(例如转义空格和防止通配符)。因此,jq 按字面意思接收 ."$var_name" 作为它的脚本——这不是你想要的。您只需要删除单引号就可以了:

echo $temp1 | jq -r ."$var_name"  <---- Does this work?

也就是说,我永远不会那样写我的剧本。我肯定想包括'。在这样的引用字符串中:

echo $temp1 | jq -r ".$var_name"  <---- Does this work?

有些人还建议您也引用“$temp1”(通常应该引用所有变量引用以防止出现空格,但这不是 echo 的问题):

echo "$temp1" | jq -r ".$var_name"  <---- Does this work?

【讨论】:

  • 这也是一个jq问题,因为使用变量替换来生成代码是不好的做法。也就是说,jq -r "$var_name"有效,但它也可以用于注入攻击(今天影响有限,因为 jq 现在无法打开文件/做其他影响安全的事情,但是有已经有人提议在未来改变这一点)
  • 就像一个可以使用双引号在awk代码中进行替换,但应该使用awk -v代替,一个可以 在 jq 代码中使用双引号进行替换,但 应该 使用 jq --arg 代替。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
  • 2011-06-20
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多