Per meno citazioni, leggi invece dallo standard input.
curl -k -X POST -H 'Content-Type: application/json' -d @- <<EOF
{ "username": "$USERNAME", "password": "$PASSWORD"}
EOF
-d @foo
legge da un file chiamato foo
. Se usi -
come nome del file, legge dallo standard input. Qui, l'input standard viene fornito da un documento here, che viene trattato come una stringa tra virgolette doppie senza racchiuderla effettivamente tra virgolette.
curl -k -X POST -H 'Content-Type: application/json' -d '{"username":"'$USERNAME'","password":"'$PASSWORD'"}'
Qui le variabili sono posizionate all'esterno di "'"
virgolette e sarà espansa dalla shell (proprio come in echo $USERNAME
). Ad esempio supponendo che USRNAME=xxx
e PASSWORD=yyy
la stringa argv[7] passata a curl
è {"username":"xxx","password":"yyy"}
E sì, questo non funzionerà quando $USERNAME o $PASSWORD contengono caratteri spazio.
Le virgolette singole inibiscono la sostituzione delle variabili, quindi utilizza le virgolette doppie. Le doppie virgolette interne devono quindi essere sfuggite.
... -d "{\"username\":\"$USERNAME\",\"password\":\"$PASSWORD\"}"
Poiché questa risposta è stata scritta nel 2015, è diventato chiaro che questa tecnica non è sufficiente per creare correttamente 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
Il problema delle quotazioni è chiaro. Le soluzioni (shell) non lo sono
Best practice attuale:utilizza uno strumento specifico per JSON per creare 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"}
E con arricciatura:
json=$( jq -n -c --arg username "$USERNAME" --arg password "$PASSWORD" '$ARGS.named' )
# or
json=$( jo "username=$USERNAME" "password=$PASSWORD" )
# then
curl ... -d "$json"