Store JSON directly in a bash script with variables?

I will preface, saying that β€œno, find another way to do this” is the acceptable answer here.

Is there a reliable way to store a short JSON bit in a bash variable for use in an AWS CLI command running from the same script?

I will be running work from Jenkins, which updates the AWS Route53 record, which requires a UPSERTing JSON file with modified records. Since it works from Jenkins, there is no local storage where I can store this file, and I would really like to avoid having to perform a git check every time this project starts (which will be once an hour).

Ideally, storing data in a variable ( $foo ) and calling it as part of the change-resource-record-sets command would be most convenient given the Jenkins setting, but I don’t know exactly how to quote / store JSON inside bash - can this be done safely?

The specific JSON in this case is as follows:

 {"Comment":"Update DNSName.","Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"alex.","Type":"A","AliasTarget":{"HostedZoneId":"######","DNSName":"$bar","EvaluateTargetHealth":false}}}]} 

As an additional complication, you must increase the value of DNSName - $bar .

+3
source share
2 answers

You can use here-doc:

 foo=$(cat <<EOF {"Comment":"Update DNSName.","Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"alex.","Type":"A","AliasTarget":{"HostedZoneId":"######","DNSName":"$bar","EvaluateTargetHealth":false}}}]} EOF ) 

If you leave EOF in the first line without quotes, the contents of this document will be subject to expansion of parameters, so your $bar will expand to what you place there.

If you can have line breaks in your JSON, you can make it more readable:

 foo=$(cat <<EOF { "Comment": "Update DNSName.", "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "alex.", "Type": "A", "AliasTarget": { "HostedZoneId": "######", "DNSName": "$bar", "EvaluateTargetHealth": false } } } ] } EOF ) 

or even (the first indent on each line should be a tab)

 foo=$(cat <<-EOF { "Comment": "Update DNSName.", "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "alex.", "Type": "A", "AliasTarget": { "HostedZoneId": "######", "DNSName": "baz", "EvaluateTargetHealth": false } } } ] } EOF ) 

and show how it is stored, including quoting (provided that bar=baz ):

 $ declare -p foo declare -- foo="{ \"Comment\": \"Update DNSName.\", \"Changes\": [ { \"Action\": \"UPSERT\", \"ResourceRecordSet\": { \"Name\": \"alex.\", \"Type\": \"A\", \"AliasTarget\": { \"HostedZoneId\": \"######\", \"DNSName\": \"baz\", \"EvaluateTargetHealth\": false } } } ] }" 

Since this extends the shell metacharacters, you may run into problems if your JSON contains something like * , so you can assign directly, but be careful when quoting $bar :

 foo='{"Comment":"Update DNSName.","Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"alex.","Type":"A","AliasTarget":{"HostedZoneId":"######","DNSName":"'"$bar"'","EvaluateTargetHealth":false}}}]}' 

Note the quote for $bar : this

 "'"$bar"'" β”‚β”‚β”‚ β”‚β”‚β”‚ β”‚β”‚β”‚ β”‚β”‚β”” literal double quote β”‚β”‚β”‚ β”‚β”” opening syntactical single quote β”‚β”‚β”‚ β”” closing syntactical double quote β”‚β”‚β”” opening syntactical double quote β”‚β”” closing syntactical single quote β”” literal double quote 
+11
source

It can be stored safely; generation is another matter as the contents of $bar may need to be encoded. Let a tool like jq create JSON.

 var=$(jq -n --arg b "$bar" '{ Comment: "Update DNSName.", Changes: [ { Action: "UPSERT", ResourceRecordSet: { Name: "alex.", Type: "A", AliasTarget: { HostedZoneId: "######", DNSName: $b, EvaluateTargetHealth: false } } } ] }') 
+7
source

Source: https://habr.com/ru/post/1266659/


All Articles