
Entonces, para enviar una solicitud POST a gists (github), puede hacer algo como esto como se ve enhttps://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
Pero, en el ejemplo anterior, el nombre del archivo y el contenido del archivo están codificados, que es la parte file1.txt":{"content":"Demo"}
...
Estoy reemplazando la parte anterior con mi variable $file":{"content":"$content"}
pero inicializo la variable, la solicitud json debe estar entre comillas dobles, lo cual hice como
curl --user "user" -X POST --data "{\"description\":\"Created via API\",\"public\":\"true\",\"files\":{\"$file\":{\"content\":\"$content\"}}' https://api.github.com/gists
Pero esto no funciona, aparece un error json.
{
"message": "Problems parsing JSON",
"documentation_url": "https://developer.github.com/v3/gists/#create-a-gist"
}
Incluso, si reemplazara todas las comillas dobles escapadas por \'
comillas simples.
¿Alguien sabe cómo incluir una variable dentro de esta solicitud json? Por cierto: he usado todos los encabezados como
-H "Content-Type: application/json; charset=UTF-8"
y muchas combinaciones para validar la solicitud pero fue en vano
ACTUALIZAR.
Así es como se ve todo el contenido.
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
}
ACTUALIZACIÓN 2
El archivo que hace que el script se rompa (el archivo que estoy intentando cargar es)
<?php echo 'hello world' ?>
Respuesta1
No muestra qué valor ha establecido para $file o $content. ¿A qué se expanden ambos? Es probable que uno, el otro o ambos contengan caracteres que no le gustan al analizador JSON. Lo más probable es que algo dentro del valor de expansión de la variable deba escaparse o codificarse aún más antes de enviarlo al analizador JSON a través de curl.
¿Ha EXPORTADO las variables de entorno?
Intentar:
echo "$archivo $contenido";
para asegurarse de que ambos estén configurados como espera.
Respuesta2
No especificó qué shell está utilizando, pero todo lo que esté entre comillas dobles está sujeto a la expansión del nombre de archivo del shell. En particular, {} tiene significado para la mayoría de los shells. Esa es la razón por la que el ejemplo que citó usó comillas simples para envolver todo.
Escapar de Shell es complicado y, a veces, parece imposible conseguir lo que quieres. Honestamente, en casos como este, escribiría un script de Python para llamar a curl, donde sé que el shell no me está "ayudando".
Respuesta3
Dado que esto fue rechazado para revisión, aquí hay otra respuesta.
Escape las partes por separado (cierre el primer escape, luego escape su variable):
curl --user "user" -X POST --data '{"description":"Created via API","public":"true","files":{"'"${file}"'":{"content":"'"${content}"'"}}}' https://api.github.com/gists
o dividir para facilitar la lectura:
'{"description":"Created via API","public":"true","files":{"'
"${file}"
'":{"content":"'
"${content}"
'"}}}'
Es posible que también tenga que cambiar o no el separador de campo interno, para que el shell no interprete ningún espacio en blanco en sus variables.
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}"
Para que esto funcione correctamente, por supuesto, aún necesitarás escapar de todos los caracteres que romperían JSON., en el contenido de su archivo, como "
caracteres de control (retornos de carro de DOS), etc.
Es... lamentable que hayan decidido utilizar estructuras de datos JSON paracontenido del archivocargas.
Si se me permite sugerir una forma diferente de crear Gists, use la curl
llamada API solo para crear un único archivo, digamos README
con algún contenido repetitivo (no puede estar vacío).
Luego, grep la estructura json devuelta paragit_push_url
yclonel repositorio esencial de git. Después de eso, puede simplemente git commit
ir git push
a lo esencial sin preocuparse por los datos binarios o los problemas de escape.
Respuesta4
Aquí hay una solución, pero supone dos cosas.
Que file
es un nombre de archivo proporcionado al script como primer argumento. Y content
el contenido del archivo es text
.
También tenga en cuenta una URL de publicación diferente a la suya (consulte la explicación a continuación).
#!/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
El archivo content.txt contiene:
This is content of the content file.
Ejecución de ejemplo:
./curl.sh content.txt
Salida de ejemplo:
{
"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"
}
NOTAS:
Estoy usando aquí el https://postman-echo.com/post
sitio web que se hace eco de todo lo que publicas como JSON.
Si el contenido del archivo content.txt es más complicado, esta solución puede fallar, ya que aún será necesario escaparlo correctamente. El contenido se coloca en el campo "contenido", por lo que aquí se aplican todas las reglas de escape para json.
Para ver la respuesta bellamente mostrada (como el json anterior), agregue al final del curl | jq .
(es posible que deba instalarlo primero):
https://postman-echo.com/post | jq .
Es posible utilizarlo jq
para citar automáticamente el archivo de contenido completo (si es necesario para un uso más avanzado):
$ 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"
Tendrás que modificar ligeramente el script curl.sh
para que funcione:
content=$(jq -Rs '.' $1)