Экранированные строки, отправленные в данных curl при использовании application/json

Экранированные строки, отправленные в данных curl при использовании application/json

Я использую CURL для отправки данных JSON. Вот пример:

mycomputer$ curl -H "Content-Type: application/json" 
     -d  "{ "some_string": "Hello mom it's me!" }"
     "http://localhost:3001/api_v2/blocks/42af6ab04d9d9635a97f8abec14ed023?api_key=fe5cf0d86af27c086ab5cd4d0eab6641"

Как мне экранировать содержимое любого значения для some_string?

Например, если кто-то захочет вставить строку, Abe Lincoln's favorite character is the backslash \. He said "I love the \ and single quotes like ''".как мне избежать этого при использовании curl?

Я думаю, мне нужно сделать следующее:

  • Если строка содержит "escape-последовательность, то она заменяется тройной обратной косой чертой \\\".

  • Если строка содержит 'экранированный символ, то экранировать его не нужно '.

  • Если строка содержит \escape-последовательность, то она заменяется тройной обратной косой чертой \\\\.

Есть ли какие-то персонажи, которых я забыл?

решение1

Я предполагаю, что ваша цель — просто провести строку через синтаксический анализ оболочки. Если так, используйте read:

Например

$ IFS='' read -r var

Затем вручную вставьте строку.

Если строк несколько, можно использовать:

$ IFS='' read -r -d '' var

И вставьте еще раз, но на этот раз используйте CTRL+ dдля завершения ввода.

Или используйте heredoc:

$ IFS='' read -r -d '' var <<'EOF'
{ "some_string": "Hello mom it's me!" }
EOF

 

Какой бы метод вы ни использовали, для доступа к нему вы можете просто использовать переменную $var:

$ curl -H "Content-Type: application/json" \
 -d  "$var" \
 "http://localhost:3001/api_v2/blocks/42af6ab04d9d9635a97f8abec14ed023?api_key=fe5cf0d86af27c086ab5cd4d0eab6641"

решение2

Вам, вероятно, не понадобятся 3 из этих обратных слешей, если вы сможете убрать оболочку из уравнения. К счастью, вы можете:

curl --config - <<\DATA
    url    = "http://some.url"
    header = "Content-Type: application/json"
    data   = "{ \"some_string\": "Abe Lincoln's favorite character is the backslash \\. He said \"I love the \\ and single quotes like '.\""
#END
DATA

Посмотрите на man curl. Я предлагаю обратить пристальное внимание на различия между--data-ascii (что и -dозначает), --data-binary, и --data-urlencoded.

Вы также можете сравнить различные варианты поведения, которые вы получаете с --header, --data, и--form (которые, по умолчанию, все делают это POSTнемного по-разному), и что вы можете получить с помощью --getкоторого вместо этого можно закодировать данные, указанные с помощью любого из ранее упомянутых, в URL-адрес запроса, следующий за ?.

решение3

Рассмотрите возможность использования инструмента с поддержкой JSON для создания документа JSON.

С использованием jq:

json=$(
    jq -n --arg 'Some key "string"' "My cat's useless" '$ARGS.named'
)

С использованием jo:

json=$( jo 'Some key "string"'="My cat's useless" )

Обратите внимание, что joбудет предпринята попытка сделать вывод, что значение является записью массива, если значение ключа заканчивается на [].

В обоих вариантах кода выше jsonпеременная получит значение, эквивалентное

{
  "Some key \"string\"": "My cat's useless"
}

Затем вы можете использовать jsonпеременную в своем вызове curl:

curl -H 'Content-Type: application/json' \
    -d "$json" \
    'http://localhost:3001/api_v2/some/endpoint'

Связанный контент