假设我有一个index.php
包含以下内容的文件:
<?= "Hello" ?>
<?= echo "WORLD" ?>
我想将此文件的内容上传到 github 中的 gists,我通过以下方式进行操作
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
现在,这个脚本由于某种原因无法工作,并且我收到错误响应
{
"message": "Problems parsing JSON",
"documentation_url": "https://developer.github.com/v3/gists/#create-a-gist"
}
如果我把所有内容写在一行中,没有标签,引用就像hello
它的工作一样
答案1
您的 JSON 字符串中存在语法错误。请检查并更正。例如
$ 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)
因此,您缺少一个花括号,您打开了 3 个花括号,但关闭了 2 个花括号。
简化的语法应该是这样的:
$ 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"
}
然后就是转义引号的问题,但是你以错误的方式转义了它,请参阅:如何在单引号字符串中转义单引号?例如:
$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc
由于您要导入也包含双引号的外部文件,因此您也应该使用诸如 等工具对它们进行双引号处理。sed
对于新行,也是一样,您应该根据预期的格式将它们更改为适当的控制字符( 或<br>
)\n
。
因此,你的最终示例将如下所示:
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
答案2
您可以使用此解决方案要替换新行,还必须在content
&description
字段中转义双引号:
#!/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