Usando curl POST con variables definidas en funciones de script bash


Cuando echo obtengo esto, que se ejecuta cuando lo introduzco en el terminal

curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data '{"account":{"email":"[email protected]","screenName":"akdgdtk","type":"NIKE","passwordSettings":{"password":"Starwars1","passwordConfirm":"Starwars1"}},"firstName":"Test","lastName":"User","middleName":"ObiWan","locale":"en_US","registrationSiteId":"520","receiveEmail":"false","dateOfBirth":"1984-12-25","mobileNumber":"9175555555","gender":"male","fuelActivationDate":"2010-10-22","postalCode":"10022","country":"US","city":"Beverton","state":"OR","bio":"This is a test user","jpFirstNameKana":"unsure","jpLastNameKana":"ofthis","height":"80","weight":"175","distanceUnit":"MILES","weightUnit":"POUNDS","heightUnit":"FT/INCHES"}' https://xxx:[email protected]/xxxxx/xxxx/xxxx

Pero cuando se ejecuta en el archivo de script bash, obtengo este error

curl: (6) Could not resolve host: application; nodename nor servname provided, or not known
curl: (6) Could not resolve host: is; nodename nor servname provided, or not known
curl: (6) Could not resolve host: a; nodename nor servname provided, or not known
curl: (6) Could not resolve host: test; nodename nor servname provided, or not known
curl: (3) [globbing] unmatched close brace/bracket at pos 158

Este es el código en el archivo

curl -i \
-H '"'Accept: application/json'"' \
-H '"'Content-Type:application/json'"' \
-X POST --data "'"'{"account":{"email":"'$email'","screenName":"'$screenName'","type":"'$theType'","passwordSettings":{"password":"'$password'","passwordConfirm":"'$password'"}},"firstName":"'$firstName'","lastName":"'$lastName'","middleName":"'$middleName'","locale":"'$locale'","registrationSiteId":"'$registrationSiteId'","receiveEmail":"'$receiveEmail'","dateOfBirth":"'$dob'","mobileNumber":"'$mobileNumber'","gender":"'$gender'","fuelActivationDate":"'$fuelActivationDate'","postalCode":"'$postalCode'","country":"'$country'","city":"'$city'","state":"'$state'","bio":"'$bio'","jpFirstNameKana":"'$jpFirstNameKana'","jpLastNameKana":"'$jpLastNameKana'","height":"'$height'","weight":"'$weight'","distanceUnit":"MILES","weightUnit":"POUNDS","heightUnit":"FT/INCHES"}'"'" "https://xxx:[email protected]/xxxxx/xxxx/xxxx"

Asumo que hay un problema con mis comillas, pero he jugado mucho con ellas y he tenido errores similares. Todas las variables se definen con diferentes funciones en el script actual

Author: AGleasonTU, 2013-06-10

5 answers

No es necesario pasar las comillas que encierran los encabezados personalizados a curl. También, sus variables en el medio del argumento data deben ser citadas.

Primero, escribe una función que genere los datos post de tu script. Esto te salva de todo tipo de dolores de cabeza con respecto a las citas de shell y hace que sea más fácil leer y mantener el script que alimentar los datos del post en la línea de invocación de curl como en tu intento:

generate_post_data()
{
  cat <<EOF
{
  "account": {
    "email": "$email",
    "screenName": "$screenName",
    "type": "$theType",
    "passwordSettings": {
      "password": "$password",
      "passwordConfirm": "$password"
    }
  },
  "firstName": "$firstName",
  "lastName": "$lastName",
  "middleName": "$middleName",
  "locale": "$locale",
  "registrationSiteId": "$registrationSiteId",
  "receiveEmail": "$receiveEmail",
  "dateOfBirth": "$dob",
  "mobileNumber": "$mobileNumber",
  "gender": "$gender",
  "fuelActivationDate": "$fuelActivationDate",
  "postalCode": "$postalCode",
  "country": "$country",
  "city": "$city",
  "state": "$state",
  "bio": "$bio",
  "jpFirstNameKana": "$jpFirstNameKana",
  "jpLastNameKana": "$jpLastNameKana",
  "height": "$height",
  "weight": "$weight",
  "distanceUnit": "MILES",
  "weightUnit": "POUNDS",
  "heightUnit": "FT/INCHES"
}
EOF 
}

Entonces es fácil usar esa función en la invocación de rizo:

curl -i \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
-X POST --data "$(generate_post_data)" "https://xxx:[email protected]/xxxxx/xxxx/xxxx"

Dicho esto, aquí hay algunas aclaraciones sobre las reglas de cotización de shell:

Las comillas dobles en los argumentos -H (como en -H "foo bar") le dicen a bash que mantenga lo que hay dentro como un solo argumento (incluso si contiene espacios).

Las comillas simples en el argumento --data (como en --data 'foo bar') hacen lo mismo, excepto que pasan todo el texto literalmente (incluidos los caracteres de comillas dobles y el signo del dólar).

Para insertar una variable en el medio de un texto entre comillas, debe termina la comilla simple, concatena con la variable entre comillas dobles y vuelve a abrir la comilla simple para continuar el texto: 'foo bar'"$variable"'more foo'.

 184
Author: Sir Athos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-25 14:13:17

Solución probada con https://httpbin.org / y script bash en línea
1. Para variables sin espacios es decir, 1:
Simplemente agregue ' antes y después de $variable al reemplazar lo deseado string

for i in {1..3}; do \
  curl -X POST -H "Content-Type: application/json" -d \
    '{"number":"'$i'"}' "https://httpbin.org/post"; \
done

2. Para la entrada con espacios:
Ajustar variable con " adicional, es decir, "el a":

declare -a arr=("el a" "el b" "el c"); for i in "${arr[@]}"; do \
  curl -X POST -H "Content-Type: application/json" -d \
    '{"elem":"'"$i"'"}' "https://httpbin.org/post"; \
done

Wow funciona:)

 47
Author: pbaranski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-12 05:10:08

Curl puede publicar datos binarios de un archivo, por lo que he estado utilizando la sustitución de procesos y aprovechando los descriptores de archivo cada vez que necesito publicar algo desagradable con curl y todavía quiero acceso a los vars en el shell actual. Algo como:

curl "http://localhost:8080" \
-H "Accept: application/json" \
-H "Content-Type:application/json" \
--data @<(cat <<EOF
{
  "me": "$USER",
  "something": $(date +%s)
  }
EOF
)

Esto termina pareciendo --data @/dev/fd/<some number> que simplemente se procesa como un archivo normal. De todos modos, si quieres ver que funciona localmente, simplemente ejecuta nc -l 8080 primero y en un shell diferente dispara el comando anterior. Verás algo. como:

POST / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.43.0
Accept: application/json
Content-Type:application/json
Content-Length: 43

{  "me": "username",  "something": 1465057519  }

Como puede ver, puede llamar a subcells y demás, así como a vars de referencia en el heredoc. Feliz hacking espero que esto ayude con el '"'"'""""'''""''.

 17
Author: Che Ruisi-Besares,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-04 16:37:07
  • la información de Sir Athos funcionó perfectamente !!

Así es como tuve que usarlo en mi script curl para CouchDB. Realmente ayudó salgo mucho. ¡Gracias!

bin/curl -X PUT "db_domain_name_:5984/_config/vhosts/$1.couchdb" -d '"/'"$1"'/"' --user "admin:*****"
 3
Author: thargenediad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-06 17:10:56

Algunos años tarde, pero esto podría ayudar a alguien si está utilizando eval o sustitución de backtick:

postDataJson="{\"guid\":\"$guid\",\"auth_token\":\"$token\"}"

Usando sed para quitar las citas del principio y el final de la respuesta

$(curl --silent -H "Content-Type: application/json" https://${target_host}/runs/get-work -d ${postDataJson} | sed -e 's/^"//' -e 's/"$//')
 2
Author: glyph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-17 03:42:40