Join the Stack Overflow Community
Stack Overflow is a community of 6.6 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I want to send a json request and embedd a variable in the post data. I did a little research and I came up with the single quotes around the variable.

    #!/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

Unfortunately I get some errors:

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"}

Appearently there are some problems with the braces and the http answer states, that the command could not be executed. What's wrong with my code here? Thanks!

This is my curl version:

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 
share|improve this question
    
This seems like a high probability candidate curl: (6) Couldn't resolve host '—d'. Do a man curl and search for --data. Good luck. – shellter Jan 29 '14 at 20:13
1  
The character before the d option seems to be some special typographic dash? – halfbit Jan 29 '14 at 20:43
    
@halfbit : Good catch! (good name!) – shellter Jan 29 '14 at 20:53
    
@halfbit Wow, did not notice that! Must have happened through a lot of copy pasting! Thanks – tzippy Jan 29 '14 at 20:56
    
There seems to be a problem when my Variable has spaces. How can I put extra quotes around that? – tzippy Jan 29 '14 at 20:58

Update: use the simpler

request_body=$(cat <<EOF
{
  "jsonrpc": "2.0",
  "method": "Player.Open",
  "params": {
    "item": {
      "file": "$FILENAME"
    }
  }
}
EOF
)

rather than what I explain below. However, if it is an option, use jq to generate the JSON instead. This ensures that the value of $FILENAME is properly quoted.

request_body=$(jq -n --arg fname "$FILENAME" '
{
  jsonrpc: "2.0",
  method: "Player.Open",
  params: {item: {file: $fname}}
}'

It would be simpler to define a variable with the contents of the request body first:

#!/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

This definition might require an explanation to understand, but note two big benefits:

  1. You eliminate a level of quoting
  2. You can easily format the text for readability.

First, you have a simple command substitution that reads from a file:

$( < ... )   # bash improvement over $( cat ... )

Instead of a file name, though, you specify a process substitution, in which the output of a command is used as if it were the body of a file.

The command in the process substitution is simply cat, which reads from a here document. It is the here document that contains your request body.

share|improve this answer
    
stuck a clever trick. Thanks. It's perfect solution. – Sachin Divekar Oct 23 '15 at 10:35
    
Just curious what is wrong with just request_body=$(cat <<EOF ... EOF)? – smac89 Sep 19 '16 at 5:20
    
@smac89 I honestly could not tell you why I wrote $(< <(...)) instead of $(...). I might have been juggling a couple of different ideas in my head while writing this, which often results in a bizarre, complicated hybrid that I fail to simplify. – chepner Sep 19 '16 at 13:32

My suggestion:

#!/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

The differences are hyphen in -d (instead of a dash) and double quotes around $FILENAME.

share|improve this answer

Here is another way to insert data from a file into a JSON property. This solution is based on a really cool command called jq.

Below is an example which prepares request JSON data, used to create a CoreOS droplet on 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\"}")
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.