web-dev-qa-db-fra.com

Utilisation de curl POST avec des variables définies dans les fonctions de script bash

Quand j'écho, j'obtiens ceci, qui court quand je l'entre dans le 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

Mais lorsqu’il est exécuté dans le fichier de script bash, j’obtiens cette erreur.

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

c'est le code dans le fichier

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"

Je suppose que mes guillemets posent problème, mais j'ai beaucoup joué avec eux et j'ai des erreurs similaires. Toutes les variables sont définies avec des fonctions différentes dans le script actuel

130
AGleasonTU

Vous n'avez pas besoin de passer les guillemets contenant les en-têtes personnalisés à curl. De plus, vos variables au milieu de l'argument data devraient être citées.

Commencez par écrire une fonction qui génère les données de publication de votre script. Cela vous évite toutes sortes de maux de tête concernant les citations de Shell et facilite la lecture et la maintenance du script par rapport au chargement des données de publication sur la ligne d'invocation de curl, comme dans votre tentative:

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
}

Il est alors facile d’utiliser cette fonction dans l’appel de curl:

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

Cela dit, voici quelques précisions sur les règles de citation de Shell:

Les guillemets doubles dans les arguments -H (comme dans -H "foo bar") indiquent à bash de conserver le contenu interne sous la forme d'un seul argument (même s'il contient des espaces).

Les guillemets simples dans l'argument --data (comme dans --data 'foo bar') font la même chose, sauf qu'ils transmettent intégralement le texte (y compris les caractères de guillemet double et le signe dollar).

Pour insérer une variable au milieu d'un texte cité entre guillemets, vous devez mettre fin à la citation simple, puis concaténer avec la variable entre guillemets et rouvrir le guillemet simple pour continuer le texte: 'foo bar'"$variable"'more foo'.

218
Sir Athos

Solution testée avec https://httpbin.org/ et script bash en ligne
1. Pour les variables sans espaces, c.-à-d. 1:
Ajoutez simplement ' avant et après $variable lors du remplacement de la chaîne souhaitée

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

2. Pour les entrées avec des espaces:
Variable d'encapsulation avec ", c'est-à-dire "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 fonctionne :)

70
pbaranski

Curl peut publier des données binaires à partir d'un fichier. J'utilise donc la substitution de processus et profite des descripteurs de fichier chaque fois que je dois publier quelque chose de désagréable avec curl tout en voulant accéder aux vars du shell en cours. Quelque chose comme:

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

Cela ressemble à --data @/dev/fd/<some number> qui est traité comme un fichier normal. Quoi qu'il en soit, si vous voulez que cela fonctionne localement, lancez d'abord nc -l 8080 et, dans un autre shell, lancez la commande ci-dessus. Vous verrez quelque chose comme:

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  }

Comme vous pouvez le voir, vous pouvez appeler des sous-coques et autres, ainsi que des références dans l’hérédoc. Heureux piratage espère que cela aide avec le '"'"'""""'''""''.

25

Quelques années de retard, mais cela pourrait aider quelqu'un si vous utilisez la substitution eval ou backtick:

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

Utilisation de sed pour supprimer les guillemets du début et de la fin de la réponse

$(curl --silent -H "Content-Type: application/json" https://${target_Host}/runs/get-work -d ${postDataJson} | sed -e 's/^"//' -e 's/"$//')
7
glyph
  • l'info de Sir Athos a parfaitement fonctionné !!

Voici comment j'ai dû l'utiliser dans mon script curl pour couchDB. Cela m'a beaucoup aidé. Merci!

bin/curl -X PUT "db_domain_name_:5984/_config/vhosts/$1.couchdb" -d '"/'"$1"'/"' --user "admin:*****"
4
user3416297