2013-06-10 11 views
85

Wenn ich echo ich das bekommen, was läuft, wenn ich es in das Terminal eingebenMit curl POST mit Variablen in Bash-Skript definierten Funktionen

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 

Aber wenn es in der Bash-Skript-Datei ausführen, bekomme ich diesen Fehler

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 

dies ist der Code in der Datei

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" 

ich nehme ein Problem mit meinen Anführungszeichen gibt es, aber Ich habe viel mit ihnen gespielt und ähnliche Fehler gemacht. Alle Variablen sind mit unterschiedlichen Funktionen im aktuellen Skript definiert.

Antwort

157

Sie müssen die Anführungszeichen, die die benutzerdefinierten Header enthalten, nicht an curl übergeben. Außerdem sollten Ihre Variablen in der Mitte des data Arguments zitiert werden.

Schreiben Sie zuerst eine Funktion, die die Post-Daten Ihres Skripts generiert. Das erspart Sie alle Arten von Kopfschmerzen Shell über zitiert und macht es leichter, das Skript eines halten zu lesen, als die Post-Daten auf curl Beschwörung Linie, wie in Ihrem Versuch, Fütterung:

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 
} 

Es ist dann einfach, diese Funktion zu verwenden, in dem Aufruf von 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" 

Dieser sagt, hier sind ein paar Erklärungen über Shell zitiert Regeln:

die doppelten Anführungszeichen in den -H Argumenten (wie in -H "foo bar") bash sagen zu halten, was ist innerhalb eines einzelnen Arguments (auch wenn es Leerzeichen enthält).

Die einfachen Anführungszeichen im --data Argument (wie in --data 'foo bar') tun das gleiche, außer dass sie alle Texte wortwörtlich übergeben (einschließlich doppelte Anführungszeichen und das Dollarzeichen).

Um eine Variable in der Mitte eines einzelnen zitierten Textes einzufügen, müssen Sie das einfache Anführungszeichen beenden, dann mit der doppelt zitierten Variablen verketten und das einfache Anführungszeichen erneut öffnen, um den Text fortzusetzen: 'foo bar'"$variable"'more foo'.

+5

"'" $ "'" löste mein Problem w hier brauchte ich Zitate, um nicht weggelassen zu werden. Vielen Dank. – baltoro

+0

Sie haben mein Skript gespeichert .. danke. :) –

+1

Diese Lösung funktioniert, aber ich denke, Sie können die zusätzlichen doppelten Anführungszeichen um die Variable ausgeben. Anstatt also: --data '{"account": {"email": "'" $ email "'"}}' können Sie dies tun: --data '{"account": {"email ":" '$ email' "}} ' – twistedstream

2
  • die info von Sir Athos hat perfekt funktioniert !!

Hier ist, wie ich es in meinem Curl-Skript für CouchDB verwenden musste. Es hat wirklich geholfen viel heraus. Vielen Dank!

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

Locken können binäre Daten aus einer Datei veröffentlichen, so habe ich Prozess Substitution mit und Deskriptoren Vorteile Datei nehmen, wenn ich etwas Gemeines mit curl schreiben muß und immer noch Zugang zu dem Vars in dem aktuell Shell will. Etwas wie:

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

Dieser windet sich die aussehen wie --data @/dev/fd/<some number>, die wie eine normale Datei verarbeitet wird. Wie auch immer, wenn Sie sehen wollen, dass es lokal funktioniert, führen Sie zuerst nc -l 8080 und in einer anderen Shell den obigen Befehl aus.Sie werden so etwas wie sehen:

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 } 

Wie Sie sehen können Sie Subshells und so weiter sowie Referenz Vars in der heredoc aufrufen können. Happy Hacking hoffe das hilft mit der '"'"'""""'''""''.

+1

Die andere Antwort funktionierte nicht für mich, da ich versuchte, sie in einem Alarm von Zabbix aufzurufen. Dieser löst es perfekt und ist sauberer. – 0rkan

+0

Aber was, wenn Sie den Code in eine Bash-Funktion setzen: myFunction() {....}? – Hanynowsky

+0

ist es wert zu beachten, dass dieses Rezept nur funktioniert, wenn das Skript wortwörtlich kopiert wird (d. H. Keine Neuformatierung EOF, geschweifte Klammern usw.) –

31

Lösung mit https://httpbin.org/ und Inline-Bash-Skript getestet
1. Für Variablen ohne Leerzeichen in es heißt 1:
Einfach ' hinzufügen vor und nach $variable wenn gewünscht Ersetzens Zeichenfolge

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

Für Eingabe mit Leerzeichen:
Umbruchvariable mit zusätzlicher " dh "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 funktioniert :)

+0

Funktioniert nicht für wann, wenn $ i Leerzeichen enthält. :( –

+0

Können Sie ein Beispiel? – abrasadera

+0

Sure. 'I =" ​​ab "' anstelle von For-Schleife –

0

Ein paar Jahre zu spät, aber dies könnte jemand helfen, wenn Sie eval oder Graviszeichen Substitution verwenden:

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

sed Mit Anführungszeichen Streifen aus Anfang und Ende der Antwort

$(curl --silent -H "Content-Type: application/json" https://${target_host}/runs/get-work -d ${postDataJson} | sed -e 's/^"//' -e 's/"$//')