因此,为了向 gists (github) 发送 POST 请求,你可以执行以下操作:https://gist.github.com/caspyi...
curl --user "user" -X POST --data '{"description":"Created via API","public":"true","files":{"file1.txt":{"content":"Demo"}}' https://api.github.com/gists
但是,在上面的例子中,文件名和文件内容是硬编码的,即部分.. file1.txt":{"content":"Demo"}
..
我用我的变量替换上面的部分$file":{"content":"$content"}
,但初始化变量,json 请求必须用双引号括起来,我这样做了
curl --user "user" -X POST --data "{\"description\":\"Created via API\",\"public\":\"true\",\"files\":{\"$file\":{\"content\":\"$content\"}}' https://api.github.com/gists
但这不起作用,我收到 json 错误。
{
"message": "Problems parsing JSON",
"documentation_url": "https://developer.github.com/v3/gists/#create-a-gist"
}
即使我将所有转义的双引号替换为\'
单引号。
有人知道如何在这个 json 请求中包含一个变量吗?顺便说一句:我已经使用了所有标头,例如
-H "Content-Type: application/json; charset=UTF-8"
并尝试了多种组合来验证请求,但都无济于事
更新。
全部内容看起来是这样的。
function gist_controller(){
content=$(cat $1)
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
read -p "enter your password - " pass
public="false"
gist_content=$(cat $1)
curl --user "samserayo" -H "Content-Type: application/json; charset=UTF-8" -X POST -d "{ 'description': 'Created via API', 'public': 'true', 'files':{ ' '$1 ':{ 'content': '$gist_content'}}" https://api.github.com/gists
}
更新2
导致脚本中断的文件(我尝试上传的文件是)
<?php echo 'hello world' ?>
答案1
您没有显示为 $file 或 $content 设置的值。这两个值会扩展成什么?很可能其中一个或另一个或两者都包含 JSON 解析器不喜欢的字符。最有可能的是,变量扩展值中的某些内容需要进一步转义或编码,然后才能通过 curl 提交给 JSON 解析器。
您是否已导出环境变量?
尝试:
回显“$file $content”;
以确保它们都按照您期望的方式设置。
答案2
您没有指定您使用的 shell,但双引号内的任何内容都会受到 shell 文件名扩展的影响。特别是,{} 对大多数 shell 都有意义。这就是您引用的示例使用单引号包裹整个内容的原因。
Shell 转义非常棘手,有时似乎无法得到想要的东西。老实说,在这种情况下,我会编写一个 Python 脚本来调用 curl,因为我知道 shell 不会“帮助”我。
答案3
由于这个问题被列入审核范围,所以这里还有另一个答案。
分别对各部分进行转义(关闭第一个转义,然后对变量进行转义):
curl --user "user" -X POST --data '{"description":"Created via API","public":"true","files":{"'"${file}"'":{"content":"'"${content}"'"}}}' https://api.github.com/gists
或者为了易读性而拆分:
'{"description":"Created via API","public":"true","files":{"'
"${file}"
'":{"content":"'
"${content}"
'"}}}'
您可能需要或不需要更改内部字段分隔符,这样 shell 就不会解释变量本身中的任何空格。
梅威瑟:cat /tmp/myfile | ./thisscript.sh "myfilename.txt"
#!/bin/sh
FILENAME="${1}"
#CONTENT="$(cat)"
CONTENT="$(sed -e 's/"/\\"/g')" # escape stuff
OFS="${IFS}"
IFS=''
PERSONAL_ACCESS_TOKEN="e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e"
curl --user "username:${PERSONAL_ACCESS_TOKEN}" -X POST --data '{"description":"Created via API","public":"true","files":{"'"${FILENAME}"'":{"content":"'"${CONTENT}"'"}}}' https://api.github.com/gists
IFS="${OFS}"
为了使其正常工作,你当然仍然需要转义所有会破坏 JSON 的字符,在您的文件内容中,例如"
和控制字符(DOS 回车符)等。
不幸的是,他们决定使用 JSON 数据结构来文件内容上传。
如果我可以建议一种创建 Gists 的不同方法,请curl
仅使用 API 调用来创建单个文件,例如README
包含一些样板内容(不能为空)。
然后 grep 返回的 json 结构git_push_url
和克隆gist git repo。之后,您就可以直接将内容添加到 gist git commit
,git push
而不必担心二进制数据或转义问题。
答案4
这是一个解决方案,但它假设了两件事。
是file
作为第一个参数提供给脚本的文件名。 是content
文件内容text
。
另请注意与您的不同的 POST URL(请参阅下面的解释)。
#!/bin/bash
file=$1
content=$(cat $1)
curl -H "Content-Type: application/json; charset=UTF-8" -X POST -d "{ 'description': 'Created via API', 'public': 'true', 'files':{ ' '${file}':{ 'content': '${content}'}}" https://postman-echo.com/post
content.txt 文件包含:
This is content of the content file.
示例运行:
./curl.sh content.txt
示例输出:
{
"args": {},
"data": "{ 'description': 'Created via API', 'public': 'true', 'files':{ ' 'content.txt ':{ 'content': 'This is content of the content file.'}}",
"files": {},
"form": {},
"headers": {
"x-forwarded-proto": "https",
"host": "postman-echo.com",
"content-length": "134",
"accept": "*/*",
"content-type": "application/json; charset=UTF-8",
"user-agent": "curl/7.65.3",
"x-forwarded-port": "443"
},
"json": null,
"url": "https://postman-echo.com/post"
}
笔记:
我在这里使用这个https://postman-echo.com/post
网站,它会将您发布的所有内容以 JSON 格式回显。
如果 content.txt 文件的内容更复杂,此解决方案可能会失效,因为它仍必须正确转义。内容被放入“content”字段,因此 json 的所有转义规则都适用于此处。
为了看到漂亮显示的响应(如上面的 json 所示),请在 curl 末尾添加| jq .
(您可能需要先安装它):
https://postman-echo.com/post | jq .
可以使用jq
自动引用整个内容文件(如果需要更高级的用法):
$ jq -Rs '.' content.txt
"This is just a text.\n"
$ jq -Rs '.' content.cpp
"#include <iostream>\nusing namespace std;\nint main() \n{\n cout << \"Hello, World!\";\n return 0;\n}\n"
您必须稍微修改一下脚本curl.sh
才能使其正常工作:
content=$(jq -Rs '.' $1)