Je vais faire une préface en disant que "non, trouver une autre façon de procéder" est une réponse acceptable ici.
Existe-t-il un moyen fiable de stocker un petit morceau de JSON dans une variable bash à utiliser dans une commande AWS CLI exécutée à partir du même script?
Je vais exécuter un travail à partir de Jenkins qui met à jour un enregistrement AWS Route53, ce qui nécessite UPSERTing un fichier JSON avec la modification des enregistrements. Parce qu'il s'exécute à partir de Jenkins, il n'y a pas de stockage local où je peux conserver ce fichier, et j'aimerais vraiment éviter d'avoir à faire une vérification git à chaque fois que ce projet s'exécutera (qui sera une fois par heure).
Idéalement, le stockage des données dans une variable ($foo
) Et leur appel dans le cadre de la commande change-resource-record-sets
Serait plus pratique compte tenu de la configuration de Jenkins, mais je ne sais pas exactement comment citer/stocker JSON dans bash - peut-il être fait en toute sécurité?
Le JSON spécifique dans ce cas est le suivant;
{"Comment":"Update DNSName.","Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"alex.","Type":"A","AliasTarget":{"HostedZoneId":"######","DNSName":"$bar","EvaluateTargetHealth":false}}}]}
Comme complication supplémentaire, la valeur DNSName - $bar
- doit être développée.
Vous pouvez utiliser un here-doc:
foo=$(cat <<EOF
{"Comment":"Update DNSName.","Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"alex.","Type":"A","AliasTarget":{"HostedZoneId":"######","DNSName":"$bar","EvaluateTargetHealth":false}}}]}
EOF
)
En laissant EOF
dans la première ligne sans guillemets, le contenu de l'ici-doc sera soumis à l'expansion des paramètres, donc votre $bar
s'étend à tout ce que vous y mettez.
Si vous pouvez avoir des sauts de ligne dans votre JSON, vous pouvez le rendre un peu plus lisible:
foo=$(cat <<EOF
{
"Comment": "Update DNSName.",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "alex.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "######",
"DNSName": "$bar",
"EvaluateTargetHealth": false
}
}
}
]
}
EOF
)
ou même (le premier retrait de chaque ligne doit être un onglet)
foo=$(cat <<-EOF
{
"Comment": "Update DNSName.",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "alex.",
"Type": "A",
"AliasTarget": {
"HostedZoneId": "######",
"DNSName": "baz",
"EvaluateTargetHealth": false
}
}
}
]
}
EOF
)
et pour montrer comment cela est stocké, y compris les guillemets (en supposant que bar=baz
):
$ declare -p foo
declare -- foo="{
\"Comment\": \"Update DNSName.\",
\"Changes\": [
{
\"Action\": \"UPSERT\",
\"ResourceRecordSet\": {
\"Name\": \"alex.\",
\"Type\": \"A\",
\"AliasTarget\": {
\"HostedZoneId\": \"######\",
\"DNSName\": \"baz\",
\"EvaluateTargetHealth\": false
}
}
}
]
}"
Étant donné que cela étend les métacaractères Shell, vous pouvez rencontrer des problèmes si votre JSON contient quelque chose comme *
, vous pouvez donc affecter directement, mais faites attention à ne pas citer entre $bar
:
foo='{"Comment":"Update DNSName.","Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"alex.","Type":"A","AliasTarget":{"HostedZoneId":"######","DNSName":"'"$bar"'","EvaluateTargetHealth":false}}}]}'
Notez la citation de $bar
: c'est
"'"$bar"'"
│││ │││
│││ ││└ literal double quote
│││ │└ opening syntactical single quote
│││ └ closing syntactical double quote
││└ opening syntactical double quote
│└ closing syntactical single quote
└ literal double quote
Il peut être stocké en toute sécurité; générer c'est une autre affaire, car le contenu de $bar
peut avoir besoin d'être encodé. Laissez un outil comme jq
gérer la création du JSON.
var=$(jq -n --arg b "$bar" '{
Comment: "Update DNSName.",
Changes: [
{
Action: "UPSERT",
ResourceRecordSet: {
Name: "alex.",
Type: "A",
AliasTarget: {
HostedZoneId: "######",
DNSName: $b,
EvaluateTargetHealth: false
}
}
}
]
}')