Я получил строку JSON ниже, которую я использую для передачи aws route53 change-resource-record-sets
команде для обновления текущей записи DMARC. Как вы можете видеть, значение TXT содержит ;
.
JSON="{ \"Comment\": \"Updating TXT record in $domain\",
\"Changes\": [ { \"Action\": \"UPSERT\", \"ResourceRecordSet\": { \"Name\":
\"_dmarc.${domainName}\", \"Type\": \"TXT\", \"TTL\":
3600, \"ResourceRecords\": [ { \"Value\": "\"v=DMARC1\; p=reject\; pct=100\"" } ] } } ] }"
Когда я echo $JSON
вместо всей строки JSON получил следующий вывод. Похоже, что парсинг останавливается, как только он достигает ;
.
{ "Comment": "Updating TXT record in ",
"Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name":
"_dmarc.contoso.com", "Type": "TXT", "TTL":
3600, "ResourceRecords": [ { "Value": "v=DMARC1;
Я пробовал множество способов избежать точки с запятой, например, используя \\;
и, но \";\"
безуспешно. Что я сделал не так?
решение1
Просто используйте сочетание одинарных и двойных кавычек, и тогда код не будет выглядеть таким запутанным и с ним будет легче работать:
JSON='{ "Comment": "Updating TXT record in $domain",
"Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name":
"_dmarc.${domainName}", "Type": "TXT", "TTL":
3600, "ResourceRecords": [ { "Value": "v=DMARC1; p=reject; pct=100" } ] } } ] }'
Это работает. Пример:
$ JSON='{ "Comment": "Updating TXT record in $domain",
"Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name":
"_dmarc.${domainName}", "Type": "TXT", "TTL":
3600, "ResourceRecords": [ { "Value": "v=DMARC1; p=reject; pct=100" } ] } } ] }'
$
$ echo $JSON | jq .
{
"Comment": "Updating TXT record in $domain",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "_dmarc.${domainName}",
"Type": "TXT",
"TTL": 3600,
"ResourceRecords": [
{
"Value": "v=DMARC1; p=reject; pct=100"
}
]
}
}
]
}
$
решение2
Оказывается, проблема здесь не в экранировании точек с запятой, а в концевом пробеле после точки с запятой. После того, как я изменил строку на что-то вроде этого
{ \"Value\": "\"v=DMARC1\;\ p=reject\;\ pct=100\"" }
Строка теперь воспроизводится правильно!
{ "Value": "v=DMARC1; p=reject; pct=100" }
решение3
Вам не хватает экранирования в нескольких кавычках и обратных косых черт в конце. Было бы проще управлять кавычками, если бы вы использовали одинарные кавычки вокруг строки документа JSON.
Похоже, что вы хотите вставить значения из переменной оболочки в документ JSON. Безопаснее всего это сделать с помощью jq
:
$ domain=my.domain.example.com
$ domainName=some-domain-name
$ JSON=$( jq -c -n --arg domain "$domain" --arg name "$domainName" '
{ "Comment": "Updating TXT record in \($domain)",
"Changes": [ {
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "_dmarc.\($name)", "Type": "TXT", "TTL": 3600,
"ResourceRecords": [ { "Value": "\"v=DMARC1; p=reject; pct=100\"" } ]
} } ] }' )
Команда jq
используется здесь для вставки значений двух переменных оболочки domain
и domainName
в встроенный документ JSON. Две переменные используются в командной строке для инициализации двух внутренних jq
переменных $domain
и $name
соответственно. На них ссылается документ JSON в строках, куда они должны быть вставлены.
Такой подход гарантирует, что любые символы, требующие специального экранирования, будут правильно экранированы для включения в строки JSON в документе.
Обратите внимание, что я оставил встроенные двойные кавычки в этой строке в конце, так как не знаю, требуются ли они или нет. Парсер JSON правильно декодирует экранированные кавычки при чтении данных.