Я использую 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'