我想发送一个json请求并在post数据中嵌入一个变量。 我做了一点研究,然后我想出了变量周围的单引号。
#!/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
答案 0 :(得分:20)
更新:使用更简单的
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
,它从此处的文档中读取。这是包含您的请求正文的here文档。
击>
答案 1 :(得分:10)
我的建议:
#!/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
周围的双引号。
答案 2 :(得分:1)
这是将文件中的数据插入JSON属性的另一种方法。
此解决方案基于一个名为jq
的非常酷的命令。
下面是一个准备请求JSON数据的示例,用于在Digital Ocean上创建CoreOS droplet:
# 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\"}")