Pour moins de citations, lisez plutôt à partir de l'entrée standard.
curl -k -X POST -H 'Content-Type: application/json' -d @- <<EOF
{ "username": "$USERNAME", "password": "$PASSWORD"}
EOF
-d @foo
lit à partir d'un fichier nommé foo
. Si vous utilisez -
comme nom de fichier, il lit à partir de l'entrée standard. Ici, l'entrée standard est fournie à partir d'un document ici, qui est traité comme une chaîne entre guillemets doubles sans l'entourer de guillemets doubles.
curl -k -X POST -H 'Content-Type: application/json' -d '{"username":"'$USERNAME'","password":"'$PASSWORD'"}'
Ici, les variables sont placées en dehors de "'"
entre guillemets et sera développé par shell (comme dans echo $USERNAME
). Par exemple, en supposant que USRNAME=xxx
et PASSWORD=yyy
la chaîne argv[7] passée à curl
est {"username":"xxx","password":"yyy"}
Et oui, cela ne fonctionnera pas lorsque $USERNAME ou $PASSWORD contiennent des espaces.
Les guillemets simples empêchent la substitution de variables, utilisez donc des guillemets doubles. Les guillemets intérieurs doivent alors être échappés.
... -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}"
Depuis que cette réponse a été écrite en 2015, il est devenu clair que cette technique est insuffisante pour créer correctement du JSON :
$ USERNAME=person1
$ PASSWORD="some \"gnarly 'password"
$ echo "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}"
{"username":"person1","password":"some "gnarly 'password"}
$ echo "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}" | jq .
parse error: Invalid numeric literal at line 1, column 47
Le problème des citations est clair. Les solutions (shell) ne le sont pas
Meilleure pratique actuelle :utilisez un outil spécifique à JSON pour créer du JSON :
-
jq
$ jq -n -c --arg username "$USERNAME" --arg password "$PASSWORD" '$ARGS.named' {"username":"person1","password":"some \"gnarly 'password"}
-
jo
$ jo "username=$USERNAME" "password=$PASSWORD" {"username":"person1","password":"some \"gnarly 'password"}
Et avec boucle :
json=$( jq -n -c --arg username "$USERNAME" --arg password "$PASSWORD" '$ARGS.named' )
# or
json=$( jo "username=$USERNAME" "password=$PASSWORD" )
# then
curl ... -d "$json"