Bash script: использовать строковую переменную в curl. Данные JSON Post
Я хочу отправить запрос json и вставить переменную в данные сообщения.
Я сделал небольшое исследование, и я придумал одинарные кавычки вокруг переменной.
#!/bin/bash
FILENAME="/media/file.avi"
curl -i -X POST -H "Content-Type: application/json" —d '{"jsonrpc": "2.0", "method": "Player.Open", "params":{"item":{"file":"'$FILENAME'"}}}' http://192.167.0.13/jsonrpc
К сожалению, я получаю некоторые ошибки:
curl: (6) Couldn't resolve host '—d'
curl: (3) [globbing] nested braces not supported at pos 54
HTTP/1.1 200 OK
Content-Length: 76
Content-Type: application/json
Date: Wed, 29 Jan 2014 19:16:56 GMT
{"error":{"code":-32700,"message":"Parse error."},"id":null,"jsonrpc":"2.0"}
По-видимому, есть некоторые проблемы с фигурными скобками и состояниями ответа HTTP, что команда не может быть выполнена. Что не так с моим кодом здесь?
Спасибо!
Это моя версия curl
:
curl 7.30.0 (mips-unknown-linux-gnu) libcurl/7.30.0 OpenSSL/0.9.8y
Protocols: file ftp ftps http https imap imaps pop3 pop3s rtsp smtp smtps tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL
Ответы
Ответ 1
Обновление: используйте более простой
request_body=$(cat <<EOF
{
"jsonrpc": "2.0",
"method": "Player.Open",
"params": {
"item": {
"file": "$FILENAME"
}
}
}
EOF
)
а не то, что я объясняю ниже. Однако, если это опция, используйте jq
для создания JSON. Это гарантирует, что значение $FILENAME
будет правильно процитировано.
request_body=$(jq -n --arg fname "$FILENAME" '
{
jsonrpc: "2.0",
method: "Player.Open",
params: {item: {file: $fname}}
}'
Было бы проще сначала определить переменную с содержимым тела запроса:
#!/bin/bash
header="Content-Type: application/json"
FILENAME="/media/file.avi"
request_body=$(< <(cat <<EOF
{
"jsonrpc": "2.0",
"method": "Player.Open",
"params": {
"item": {
"file": "$FILENAME"
}
}
}
EOF
))
curl -i -X POST -H "$header" -d "$request_body" http://192.167.0.13/jsonrpc
Это определение может потребовать объяснения, чтобы понять, но обратите внимание на два больших преимущества:
- Вы удаляете уровень цитирования
- Вы можете легко форматировать текст для удобства чтения.
Сначала у вас есть простая подстановка команды, которая читается из файла:
$( < ... ) # bash improvement over $( cat ... )
Вместо имени файла, однако, вы указываете подстановку процесса, в которой вывод команды используется так, как если бы она была телом файла.
Команда в подстановке процесса просто cat
, которая читается из документа здесь. Это документ, который содержит ваш запрос.
Забастовкa >
Ответ 2
Мое предложение:
#!/bin/bash
FILENAME="/media/file 2.avi"
curl -i -X POST -H "Content-Type: application/json" -d '{"jsonrpc": "2.0", "method": "Player.Open", "params":{"item":{"file":"'"$FILENAME"'"}}}' http://192.167.0.13/jsonrpc
Различия - это дефис в -d
(вместо тире) и двойные кавычки вокруг $FILENAME
.
Ответ 3
Вот еще один способ вставить данные из файла в свойство JSON.
Это решение основано на действительно классной команде jq
.
Ниже приведен пример, который подготавливает данные JSON запроса, используемые для создания капли CoreOS в Digital Ocean:
# Load the cloud config to variable
user_data=$(cat config/cloud-config)
# Prepare the request data
request_data='{
"name": "server name",
"region": "fra1",
"size": "512mb",
"image": "coreos-stable",
"backups": false,
"ipv6": true,
"user_data": "---this content will be replaced---",
"ssh_keys": [1234, 2345]
}'
# Insert data from file into the user_data property
request_data=$(echo $request_data | jq ". + {user_data: \"$user_data\"}")