
Um also eine POST-Anfrage an Gists (GitHub) zu senden, können Sie so etwas tun wie inhttps://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
Aber im obigen Beispiel sind der Dateiname und der Inhalt der Datei fest codiert, und das ist der Teil .. file1.txt":{"content":"Demo"}
..
Ich ersetze den obigen Teil durch meine Variable, $file":{"content":"$content"}
initialisiere aber die Variable, die JSON-Anforderung muss in doppelte Anführungszeichen eingeschlossen werden, was ich getan habe als
curl --user "user" -X POST --data "{\"description\":\"Created via API\",\"public\":\"true\",\"files\":{\"$file\":{\"content\":\"$content\"}}' https://api.github.com/gists
Aber das funktioniert nicht, ich bekomme einen JSON-Fehler.
{
"message": "Problems parsing JSON",
"documentation_url": "https://developer.github.com/v3/gists/#create-a-gist"
}
Selbst wenn ich alle maskierten Anführungszeichen durch \'
einfache Anführungszeichen ersetzt hätte.
Weiß jemand, wie man eine Variable in diese JSON-Anfrage einfügt? Übrigens: Ich habe alle Header verwendet, wie
-H "Content-Type: application/json; charset=UTF-8"
und viele Kombinationen, um die Anfrage zu validieren, aber ohne Erfolg
AKTUALISIEREN.
So sieht der gesamte Inhalt aus.
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
}
AKTUALISIERUNG 2
Die Datei, die den Abbruch des Skripts verursacht (die Datei, die ich hochzuladen versuche, ist)
<?php echo 'hello world' ?>
Antwort1
Sie zeigen nicht, welchen Wert Sie für $file oder $content festgelegt haben. Wozu werden diese beiden erweitert? Wahrscheinlich enthält einer oder der andere oder beide Zeichen, die dem JSON-Parser nicht gefallen. Höchstwahrscheinlich muss etwas innerhalb des Variablenerweiterungswerts weiter maskiert oder codiert werden, bevor es über curl an den JSON-Parser übermittelt wird.
Haben Sie die Umgebungsvariablen EXPORTIERT?
Versuchen:
echo "$Datei $Inhalt";
um sicherzustellen, dass beide wie erwartet eingestellt sind.
Antwort2
Sie haben nicht angegeben, welche Shell Sie verwenden, aber alles in Anführungszeichen unterliegt der Shell-Dateinamenerweiterung. Insbesondere {} hat für die meisten Shells eine Bedeutung. Aus diesem Grund wurden in dem von Ihnen zitierten Beispiel einfache Anführungszeichen verwendet, um das Ganze einzuschließen.
Shell-Escapes sind knifflig und manchmal scheint es unmöglich, das gewünschte Ergebnis zu erzielen. Ehrlich gesagt würde ich in solchen Fällen ein Python-Skript schreiben, um curl aufzurufen, wenn ich weiß, dass mir die Shell nicht „hilft“.
Antwort3
Da dies zur Überprüfung zurückgestellt wurde, hier eine weitere Antwort.
Escapen Sie die Teile separat (schließen Sie das erste Escape und escapen Sie dann Ihre Variable):
curl --user "user" -X POST --data '{"description":"Created via API","public":"true","files":{"'"${file}"'":{"content":"'"${content}"'"}}}' https://api.github.com/gists
oder zur besseren Lesbarkeit aufgeteilt:
'{"description":"Created via API","public":"true","files":{"'
"${file}"
'":{"content":"'
"${content}"
'"}}}'
Möglicherweise müssen Sie auch den internen Feldtrenner ändern, damit die Shell keine Leerzeichen in Ihren Variablen selbst interpretiert.
MWE: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}"
Damit dies richtig funktioniert, müssen Sie natürlich weiterhin alle Zeichen maskieren, die JSON beschädigen würden., in Ihren Dateiinhalten, wie z. B. "
und Steuerzeichen (DOS-Wagenrückläufe) usw.
Es ist ... bedauerlich, dass sie sich entschieden haben, JSON-Datenstrukturen fürDateiinhaltUploads.
Wenn ich eine andere Möglichkeit zum Erstellen von Gists vorschlagen darf, verwenden Sie den curl
API-Aufruf nur, um eine einzelne Datei zu erstellen, beispielsweise README
mit einem Boilerplate-Inhalt (darf nicht leer sein).
Dann durchsuchen Sie die zurückgegebene JSON-Struktur nachgit_push_url
UndKlondas Gist-Git-Repo. Danach können Sie einfach das Gist-Repo füllen git commit
, git push
ohne sich um Binärdaten oder Escape-Probleme kümmern zu müssen.
Antwort4
Hier ist eine Lösung, die jedoch zwei Dinge voraussetzt.
Das file
ist ein Dateiname, der dem Skript als erstes Argument übergeben wird. Und das content
ist der Dateiinhalt als text
.
Beachten Sie auch, dass es sich um eine andere POST-URL als Ihre eigene handelt (Erklärung siehe unten).
#!/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
Die Datei content.txt enthält:
This is content of the content file.
Beispiellauf:
./curl.sh content.txt
Beispielausgabe:
{
"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"
}
ANMERKUNGEN:
Ich verwende hier die https://postman-echo.com/post
Website, die alles, was Sie dort posten, als JSON wiedergibt.
Wenn der Inhalt der Datei content.txt komplizierter ist, kann diese Lösung scheitern, da er noch immer ordnungsgemäß maskiert werden muss. Der Inhalt wird in das Feld „content“ eingefügt, daher gelten hier alle Maskierungsregeln für JSON.
Um die Antwort schön angezeigt zu bekommen (wie oben im JSON), fügen Sie am Ende des Curls hinzu | jq .
(Sie müssen es möglicherweise zuerst installieren):
https://postman-echo.com/post | jq .
Es ist möglich, jq
die gesamte Inhaltsdatei automatisch zu zitieren (falls dies für eine erweiterte Nutzung erforderlich ist):
$ 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
Damit es funktioniert, müssen Sie das Skript leicht modifizieren :
content=$(jq -Rs '.' $1)