
Итак, чтобы отправить POST-запрос в gists (github), вы можете сделать что-то вроде этого, как показано в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. Скорее всего, что-то внутри значения расширения переменной необходимо дополнительно экранировать или закодировать перед отправкой парсеру JSON через curl.
Вы ЭКСПОРТировали переменные среды?
Пытаться:
echo "$файл $контент";
чтобы убедиться, что они оба настроены так, как вы ожидаете.
решение2
Вы не указали, какую оболочку вы используете, но все, что заключено в двойные кавычки, подлежит расширению имени файла оболочки. В частности, {} имеет значение для большинства оболочек. Вот почему в приведенном вами примере для всего были использованы одинарные кавычки.
Выходы из оболочки сложны, и иногда кажется невозможным получить то, что вы хотите. Честно говоря, в таких случаях я бы написал скрипт Python для вызова curl, где я знаю, что оболочка мне не «помогает».
решение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}"
'"}}}'
Вам также может потребоваться изменить внутренний разделитель полей, чтобы оболочка сама не интерпретировала пробелы в ваших переменных.
МВЭ: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. После этого вы можете просто git commit
, git push
набивать gist, не беспокоясь о бинарных данных или проблемах экранирования.
решение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)