web-dev-qa-db-fra.com

Curl avec multiline de JSON

Considérez la commande curl ci-dessous, est-il possible d'autoriser newline en JSON (sans le minify) et de l'exécuter directement en bash (Mac/Ubuntu)

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d \
'
{
    "field1": "test",
    "field2": {
        "foo": "bar"
    }
}'

Lorsque j'exécute la commande ci-dessus, une erreur s'est produite au second { Comment corriger la commande ci-dessus?

Mise à jour: en fait, j'ai pu exécuter la commande sans problème auparavant, je ne savais pas pourquoi le problème se produisait récemment.

56
Ryan

Je me suis souvenu d'une autre manière de faire ceci avec un "Here Document" comme décrit dans la page de manuel Bash et détaillé ici . Le @- signifie lire le corps de STDIN, alors que << EOF _ signifie diriger le contenu du script jusqu'à "EOF" en tant que STDIN à curl. Cette disposition peut être plus facile à lire que l’utilisation de fichiers séparés ou l’approche "écho d’une variable".

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d @- << EOF

{
    "field1": "test",
    "field2": {
        "foo": "bar"
    }
}
EOF

NOTE: Utilisez le --trace <outfile> curl option pour enregistrer exactement ce qui se passe sur le fil. Pour une raison quelconque, cette approche Here Document supprime les nouvelles lignes?!?

83
Eric Bolinger

Dans le sens de la suggestion de Martin de mettre le JSON dans une variable, vous pouvez également placer le JSON dans un fichier séparé, puis fournir le nom de fichier à -d en utilisant la syntaxe @ de curl:

curl -0 -v -X POST http://www.example.com/api/users \
  -H "Expect:" \
  -H 'Content-Type: text/json; charset=utf-8' \
  -d @myfile.json

L'inconvénient est évident (2 fichiers ou plus où vous en utilisiez un auparavant). Mais du côté positif, votre script pourrait accepter un argument de nom de fichier ou de répertoire et vous n'auriez jamais besoin de l'éditer, exécutez-le simplement sur différents fichiers JSON. Que cela soit utile dépend de ce que vous essayez d'accomplir.

25
Bampfer

Vous devez utiliser des guillemets externes et échapper à toutes les guillemets internes comme ceci:

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d \
"
{
    \"field1\": \"test\",
    \"field2\": {
        \"foo\": \"bar\"
    }
}"
14
Dmitriy Korobkov

Vous pouvez assigner votre json à une var:

json='
{
    "field1": "test",
    "field2": {
        "foo": "bar"
    }
}'

Vous pouvez maintenant transférer ceci en boucle en utilisant stdin:

echo $json | curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d @-
14
Martin Konecny

Pour une raison quelconque, cette approche Here Document supprime les nouvelles lignes

@ eric-bolinger la raison pour laquelle Heredoc supprime les nouvelles lignes est parce que vous devez demander à votre Heredoc de préserver les nouvelles lignes en citant l'EOF:

curl -0 -v -X POST http://www.example.com/api/users \
-H "Expect:" \
-H 'Content-Type: text/json; charset=utf-8' \
-d @- <<'EOF'

{
    "field1": "test",
    "field2": {
        "foo": "bar"
    }
}
EOF

Notez les ticks simples entourant EOF la première fois que c'est défini, mais pas la seconde.

10
Tim Gebhardt