JSONの複数行を使用したカール


83

以下のcurlコマンドを検討してください。JSONで改行を許可し(縮小せずに)、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"
    }
}'

上記のコマンドを実行second { すると、上記のコマンドを修正する方法でエラーが発生したようです。

更新:実際、以前は問題なくコマンドを実行できましたが、最近問題が発生した理由がわかりません。


1
エラーについて詳しく教えてください。あなたの例は私のシステムで「そのまま」機能します。 mymac > bash --version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15) Copyright (C) 2007 Free Software Foundation, Inc.
Eric Bolinger 2016年

GNU bash, version 4.3.42(1)-release
うん

1
ANSI Cのような文字列構文も確認してください:echo $'here is a newline:\nand here is a tab:\t'
miken32 2016年

application/jsonJSONデータの正しいメディア・タイプである-を参照してRFC4627
Pocketsand

回答:


121

Bashのmanページで説明され、ここ詳しく説明されているように、「ヒアドキュメント」を使用してこれを行う別の方法を思い出しました@-一方で、STDINから身体を読み込むための手段<< EOFカールにSTDINとして「EOF」までのパイプへの手段は、スクリプトの内容。このレイアウトは、個別のファイルや「変数のエコー」アプローチを使用するよりも読みやすい場合があります。

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

注:--trace <outfile>curlオプションを使用して、ネットワーク上を通過するものを正確に記録します。何らかの理由で、このヒアドキュメントアプローチは改行を取り除きます。(更新:改行はcurl -dオプションによって削除されました。修正されました!)


5
これはクリーンで、余分な引用やエスケープはなく、非常にうまく機能します。ありがとう。
セス

そのような構文でパイプを使用できますか?
Ivan Balashov 2018年

2
はい、配置は真ん中にありますが、出力を別のコマンドにパイプすることができます。stdinリダイレクトの後にstdoutリダイレクトを追加します。単語数の使用例:-d @- << EOF | wc
Eric Bolinger 2018年

2
新しい行を削除するのはヒアドキュメントではありませんが、curl -dオプション:curl.haxx.se/docs/manpage.html#-d--data-binary改行文字とキャリッジリターン文字を保持するために使用します。
dzieciou

35

JSONを変数に入れるというMartinの提案に沿って、JSONを別のファイルに入れて、-dcurlの@構文を使用してファイル名を指定することもできます。

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

欠点は明らかです(以前は2つ以上のファイルがありました)。ただし、プラス面として、スクリプトはファイル名またはディレクトリの引数を受け入れることができ、編集する必要はなく、別のJSONファイルで実行するだけです。それが役立つかどうかは、何を達成しようとしているかによって異なります。



このアプローチは、他のアプローチと比較してクリーンでデバッグが容易です。
vikramvi 2018

素晴らしいソリューション。PATHに注意してください!
ピエールフェリー

20

外側の二重引用符を使用し、次のようにすべての内側の引用符をエスケープする必要があります。

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\"
    }
}"

19

jsonをvarに割り当てることができます:

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

これで、次を使用してこれをカールに転送できます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 @-

ブロックを囲むために一重引用符を使用することは、JSONで変数(例)を使用できないことを意味します${username}
エア

はい。ただし、二重引用符を使用すると、データに$記号を使用できなくなります。どちらがあなたにぴったりかを選んでください。
Martin Konecny 2017年

19

何らかの理由で、このヒアドキュメントアプローチは改行を取り除きます

@ eric-bolingerヒアドキュメントが改行を削除する理由は、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

EOFを最初に定義したときは、EOFを囲む単一の目盛りに注意してください。ただし、2回目はそうではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.