Завиток із багаторядком 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.
Ерік Болінгер

Так, це працює і для мене:GNU bash, version 4.3.42(1)-release
miken32

1
Також перевірте синтаксис рядків, схожий на ANSI :echo $'here is a newline:\nand here is a tab:\t'
miken32

application/jsonє правильним типом носія даних JSON - див. RFC4627
Pocketsand

Відповіді:


122

Я згадав ще один спосіб зробити це за допомогою "Тут документа", як описано на сторінці Bash man і деталізовано тут . Засіб @-читати тіло зі STDIN, тоді як << EOFозначає передавати вміст сценарію до "EOF" як STDIN для згортання. Цей макет може бути легшим для читання, ніж використання окремих файлів або підходу "повторити змінну".

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 -d. Виправлено!)


5
Це чисто, без зайвих цитат, без втечі, і це працює дуже добре. Дякую.
Сет

Чи можемо ми використовувати конвеєри з таким синтаксисом?
Іван Балашов

2
Так, ви можете направити вихід до іншої команди, хоча розміщення знаходиться посередині. Додайте перенаправлення stdout після перенаправлення stdin. Приклад використання кількості слів:-d @- << EOF | wc
Ерік Болінгер,

2
Нові рядки зачищає не тут документ, а curl -dваріант: curl.haxx.se/docs/manpage.html#-d . Використовуйте --data-binaryдля збереження символів повернення нового рядка та каретки.
dzieciou

35

Нарівні з пропозицією Мартіна помістити JSON у змінну, ви також можете помістити JSON в окремий файл, а потім вказати ім'я файлу, -dвикористовуючи синтаксис @ 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

Недолік очевидний (2 або більше файлів, де раніше у вас був один.) Але плюсом є те, що ваш сценарій може прийняти ім’я файлу або аргумент каталогу, і вам ніколи не потрібно буде його редагувати, просто запустіть його на різних файлах JSON. Чи корисно це, залежить від того, що ви намагаєтесь досягти.


1
Примітка: переконайтеся, що ви допустили
vikramvi

Цей підхід є чистим і простим для налагодження порівняно з іншими.
vikramvi

Чудове рішення. Будьте обережні з PATH tho!
П’єр Феррі

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 змінному:

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 @-

Використання одинарних лапок для оточення блоку означає, що ви не можете використовувати змінні (наприклад ${username}) у JSON.
Ефір

Так, але використання подвійних лапок означає, що ви не можете використовувати знаки $ у своїх даних. Виберіть, який з них підходить саме вам.
Martin Konecny

19

Чомусь цей підхід «Тут документ» позбавляє нових рядків

@ eric-bolinger причина, по якій Heredoc позбавляє нових рядків, полягає в тому, що вам потрібно сказати своєму Heredoc зберегти нові рядки, цитуючи 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, перший раз, коли він визначений, але не другий.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.