0

I am facing issue with below commands. I need to use variable but it is returning me null whereas when I hardcode its value, it return me correct response. Can anybody help me whats the correct way of writing this command? My intension is to pull value of corresponding key passed as a variable?

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

Update: I am adding actual piece of where I am trying to use above fix. My intension is to first read all values which start with SSM_DEV_... and then get there original values from aws than replace it in. one key pair look like this --> 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

Fix: I have solved my issue which was of carriage return character. Below cmd help me:

var_name=`echo ${after:1} | tr -d '\r'`
jq -r --arg var_name "$var_name" '.[$var_name]' <<< "$result1"
Ashish Sharma
  • 574
  • 7
  • 18
  • BTW, `echo $temp1 | ...` is itself buggy; see [I just assigned a variable, but `echo $variable` shows something else!](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) – Charles Duffy Sep 14 '21 at 15:04

2 Answers2

2

You'll need to use Generic Object Index (.[$var_name]) to let know the variable should be seen as a key

The command should look like:

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

Wich will output:

Smkfnkhnb48dh

Note: <<< "$temp1" instead off the echo

0stone0
  • 34,288
  • 4
  • 39
  • 64
  • Thanks.Your answer did work for me. I want to know one more thing when I use like below it did n't work than and give me error "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; 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 – Ashish Sharma Sep 14 '21 at 15:11
  • Sorry but the code isn't readable like that. If this is part of the original question, please add it to your question, otherwise you might want to ask another one! – 0stone0 Sep 14 '21 at 15:19
  • That sound like an issue not related to the current question-scope. I'd recommend [upvoting](https://meta.stackexchange.com/questions/173399/how-can-i-upvote-answers-and-comments) or [accepting](https://meta.stackexchange.com/q/5234/179419) any answers that helped fixing this issue. Then ask another question where you carefully explain the new issue. – 0stone0 Sep 14 '21 at 15:30
0

Let's look at the following statement:

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

Your problem is actually with the shell quoting and not jq. The single quotes tell the shell not to interpolate (do variable substitution) among other things (like escaping white space and preventing globing). Thus, jq is receiving literally ."$var_name" as it's script - which is not what you want. You simply need to remove the single quotes and you'll be good:

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

That said, I would never write my script that way. I would definitely want to include the '.' in the quoted string like this:

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

Some would also suggest that you quote "$temp1" as well (typically all variable references should be quoted to protect against white space, but this is not a problem with echo):

echo "$temp1" | jq -r ".$var_name"  <---- Does this work?
Mark
  • 4,249
  • 1
  • 18
  • 27
  • It's also a jq problem, because it's bad practice to use variable substitution to generate code. That is to say, `jq -r "$var_name"` _works_, but it also can be used for injection attacks (limited impact today, since jq right now can't open files / do other security-impacting things, but there've been proposals to change that for the future) – Charles Duffy Sep 14 '21 at 15:01
  • Just as while one _can_ use double quotes to do substitutions in awk code but _should_ use `awk -v` instead, one _can_ use double quotes to do substitutions in jq code, but _should_ use `jq --arg` instead. – Charles Duffy Sep 14 '21 at 15:03