Cuộn tròn với nhiều dòng JSON


83

Hãy xem xét lệnh curl dưới đây, có thể cho phép dòng mới trong JSON (không có minify) và thực thi trực tiếp trong bash (Mac / Ubuntu) không

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

Khi tôi chạy lệnh trên, có vẻ như đã xảy ra lỗi ở phần second { Cách khắc phục lệnh trên?

Đã cập nhật : thực sự tôi đã có thể chạy lệnh mà không gặp sự cố trước đó, không rõ tại sao sự cố lại xảy ra gần đây.


1
Bạn có thể cho chúng tôi biết thêm về lỗi? Ví dụ của bạn hoạt động "nguyên trạng" trên hệ thống của tôi. mymac > bash --version GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin15) Copyright (C) 2007 Free Software Foundation, Inc.
Eric Bolinger

Yup, làm việc cho tôi cũng như:GNU bash, version 4.3.42(1)-release
miken32

1
Ngoài ra, hãy xem cú pháp chuỗi giống ANSI C :echo $'here is a newline:\nand here is a tab:\t'
miken32

application/jsonlà loại phương tiện chính xác cho dữ liệu JSON - xem RFC4627
Pockets và

Câu trả lời:


121

Tôi đã nhớ một cách khác để thực hiện việc này với "Tài liệu tại đây" như được mô tả trong trang Bash man và chi tiết tại đây . Các@- tiện để đọc phần << EOFnội dung từ STDIN, trong khi có nghĩa là ghi nội dung tập lệnh cho đến khi "EOF" dưới dạng STDIN để cuộn lại. Bố cục này có thể dễ đọc hơn so với việc sử dụng các tệp riêng biệt hoặc cách tiếp cận "lặp lại một biến".

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

LƯU Ý: Sử dụng --trace <outfile>tùy chọn cuộn tròn để ghi lại chính xác những gì đi qua dây. Vì một số lý do, phương pháp Tiếp cận Tài liệu Đây này đã xóa các dòng mới. (Cập nhật: Các dòng mới đã bị loại bỏ bởi tùy chọn curl -d. Đã sửa!)


5
Điều này là sạch sẽ, không có trích dẫn thêm, không có thoát và nó hoạt động rất tốt. Cảm ơn.
Seth

Chúng ta có thể sử dụng các đường ống với cú pháp như vậy không?
Ivan Balashov,

2
Có, bạn có thể chuyển đầu ra sang một lệnh khác, mặc dù vị trí nằm ngay giữa. Thêm chuyển hướng stdout sau chuyển hướng stdin. Ví dụ sử dụng số từ:-d @- << EOF | wc
Eric Bolinger

2
Không phải Đây là Tài liệu tách các dòng mới mà là curl -dtùy chọn: curl.haxx.se/docs/manpage.html#-d . Sử dụng --data-binaryđể giữ các ký tự xuống dòng và ký tự xuống dòng.
dzieciou

35

Cùng với đề xuất của Martin về việc đặt JSON vào một biến, bạn cũng có thể đặt JSON trong một tệp riêng biệt, rồi cung cấp tên tệp -dbằng cú pháp curl's @:

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

Điểm bất lợi là rõ ràng (2 hoặc nhiều tệp mà bạn đã từng có.) Nhưng mặt tích cực, tập lệnh của bạn có thể chấp nhận đối số tên tệp hoặc thư mục và bạn không bao giờ cần chỉnh sửa nó mà chỉ cần chạy nó trên các tệp JSON khác nhau. Điều đó có hữu ích hay không phụ thuộc vào những gì bạn đang cố gắng hoàn thành.


1
Lưu ý: chắc chắn rằng bạn đã nội dung json hợp lệ thông qua jsonlint.com
vikramvi

Cách tiếp cận này sạch sẽ và dễ gỡ lỗi so với những cách khác.
vikramvi 20/02/18

Giải pháp tuyệt vời. Hãy cẩn thận của PATH tho!
Phà Pierre

20

Bạn nên sử dụng dấu ngoặc kép bên ngoài và thoát khỏi tất cả các dấu ngoặc kép bên trong như thế này:

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

Bạn có thể gán json của mình cho var:

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

Bây giờ bạn có thể chuyển tiếp điều này để cuộn tóc bằng cách sử dụng 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 @-

Sử dụng dấu ngoặc kép để bao quanh khối có nghĩa là bạn không thể sử dụng các biến (ví dụ ${username}) trong JSON.
Air

Đúng, nhưng sử dụng dấu ngoặc kép có nghĩa là bạn không thể sử dụng dấu $ trong dữ liệu của mình. Chọn cái nào phù hợp với bạn.
Martin Konecny

19

Vì một số lý do, phương pháp Tiếp cận Tài liệu Đây này đã xóa các dòng mới

@ eric-bolinger lý do Heredoc loại bỏ các dòng mới là vì bạn cần nói với Heredoc của mình để bảo vệ các dòng mới bằng cách trích dẫn 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

Lưu ý các dấu tích xung quanh EOF trong lần đầu tiên nó được xác định, nhưng không phải lần thứ hai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.