Sending gist to github via cURL and issues with new lines inside file

1

So, let's say I have an index.php file containing this:

 <?= "Hello" ?>

 <?= echo "WORLD" ?>

And I wanted upload the contents of this file to my gists in github, which I am doing via

gist_content=$(cat 'index.php')

curl --user "GITHUB_USER"  -H "Content-Type: application/json; charset=UTF-8" -X POST -d  "{ \"description\": \"Created via API\", \"public\": \"true\", \"files\":{ \"index.php \":{ \"content\": \"$gist_content\"}}\" " https://api.github.com/gists

Now, this script does not work for some reason, and I get error response

{
  "message": "Problems parsing JSON",
  "documentation_url": "https://developer.github.com/v3/gists/#create-a-gist"
}

If I write everything in one line without tags, quotes like hello it works find

samayo

Posted 2016-05-13T14:33:49.783

Reputation: 115

Answers

1

You've some syntax error in your JSON string. Please check and correct it. E.g.

$ echo "{ \"description\": \"Created via API\", \"public\": \"true\", \"files\":{ \"index.php \":{ \"content\": \"$gist_content\"}}\" " | python -m json.tool
Expecting ',' delimiter: line 1 column 95 (char 94)

So you're missing one of the curly brackets, you're opening 3, but closing 2.

The simplified syntax should be like:

$ echo '{"description": "Created via API", "public": "true", "files": { "index.php": { "content": "foo" } } }' | python -m json.tool
{
    "description": "Created via API",
    "files": {
        "index.php": {
            "content": "foo"
        }
    },
    "public": "true"
}

Then it's matter of escaping the quotes, but you're escaping it in the wrong way, see: How to escape single-quotes within single-quoted strings? For example:

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

Since you're importing external file which consist double-quotes as well, you should double quote them as well using tools such as sed, etc. The same with new lines, you should change them into appropriate control characters (either <br> or \n) depending on the expected format.

So your final example would look like:

gist_content=$(cat index.php | sed 's/"/\\"/g' | paste -s -d '\\n' -)
curl --user "GITHUB_USER" -H "Content-Type: application/json; charset=UTF-8" -X POST -d "{"\""description"\"": "\""Created via API"\"", "\""public"\"": "\""true"\"", "\""files"\"": { "\""index.php"\"": { "\""content"\"": "\""$gist_content"\"" } } }" https://api.github.com/gists

kenorb

Posted 2016-05-13T14:33:49.783

Reputation: 16 795

If I started the JSON request with single quotes, then $gist_content won't be evaluated. – samayo – 2016-05-13T14:57:54.933

When you use with double-quotes you need to escape it, but your escaping is not correct. Let me update the post, but my computer is bloody slow. You need to do like: " "\"" " to escape a single double-quote. Secondly your JSON has uneven number brackets, or something. – kenorb – 2016-05-13T15:03:30.860

I am saying, if I use single quotes the bash $variable won't be read. You can try and then let me know, if it works for you – samayo – 2016-05-13T15:13:38.917

@samayo I know, I'm just saying you've the syntax error in your JSON, so you can do the rest. I just simplified the example for you to show you what is the valid JSON format and I've explained where is the issue, so you can fix it by yourself by understanding the problem. You've just a typo, that's all. – kenorb – 2016-05-13T15:14:30.337

like I said, your final example gives me the same error I posted in the question. It is a tricky situation. – samayo – 2016-05-13T15:22:53.983

You also need to escape your file content as well. Or use single quotes inside the index.php. – kenorb – 2016-05-13T16:16:48.820

Check out the first block of code in my question, the php code does not need escaping as it contains no error, so is there anyway to escape the content automatically with bash? – samayo – 2016-05-13T16:26:30.553

PHP has double-quotes which you're injecting into your JSON, so they're in conflict with other double-quotes. So PHP's double-quotes needs escaping, as well as new lines. Updated. – kenorb – 2016-05-13T16:46:04.387

+1 for the effort, but I get the same error despite your update. The problem is not as easy as it seems. – samayo – 2016-05-13T16:59:31.350

It works for me. You should update your question with relevant details, if still doesn't work. – kenorb – 2016-05-13T20:46:13.027

You mean you were able to send the gist with the contents from the index.php file? – samayo – 2016-05-13T21:12:03.883

I didn't have any syntax error which you've mentioned as it generated JSON format correctly (in comparison to yours which had a syntax error), but I haven't tested gist request, since I've 2-factor auth, so I couldn't fully test it. Although your original code included in your question where you've syntax error is now corrected. – kenorb – 2016-05-13T21:24:40.133

1

You can use this solution to replace new lines, Also you have to escape double quotes in the content & description field :

#!/bin/bash

ACCESS_TOKEN="YOUR_ACCESSS_TOKEN"

description="the description for this gist. There are also some quotes 'here' and \"here\" in that description"
public="true"
filename="index.php"

desc=$(echo "$description" | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
json=$(cat index.php | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')

curl -v -H "Content-Type: text/json; charset=utf-8" \
        -H "Authorization: Token $ACCESS_TOKEN" \
        -X POST https://api.github.com/gists -d @- << EOF
{ 
  "description": "$desc", 
  "public": "$public", 
  "files": { 
      "$filename" : { 
          "content": "$json"
       } 
   } 
}
EOF

Bertrand Martel

Posted 2016-05-13T14:33:49.783

Reputation: 111