15

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 
5
  • This seems like a high probability candidate curl: (6) Couldn't resolve host '—d'. Do a man curl and search for --data. Good luck. Commented Jan 29, 2014 at 20:13
  • 1
    The character before the d option seems to be some special typographic dash? Commented Jan 29, 2014 at 20:43
  • There seems to be a problem when my Variable has spaces. How can I put extra quotes around that? Commented Jan 29, 2014 at 20:58
  • Remove this single quotes directly around the variable, and it should be fine. You're trying to nest single quotes with no escaping or anything, so $FILENAME ends up being not surrounded by single quotes. Commented Jan 29, 2014 at 21:30
  • stackoverflow.com/questions/8903222/… I ran into this same problem, and the answer below didn't help. This however did. Commented Mar 23, 2015 at 18:49

3 Answers 3

22

You can use:

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

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}}
}'
Sign up to request clarification or add additional context in comments.

2 Comments

Just curious what is wrong with just request_body=$(cat <<EOF ... EOF)?
@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.
13

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.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.