Đếm số lượng byte được truyền từ quy trình này sang quy trình khác


17

Tôi đang chạy tập lệnh shell chuyển dữ liệu từ quy trình này sang quy trình khác

process_a | process_b

Có ai biết một cách để tìm hiểu có bao nhiêu byte được truyền qua giữa hai chương trình không? Giải pháp duy nhất tôi có thể nghĩ đến lúc này là viết một chương trình c nhỏ đọc từ stdin, ghi vào thiết bị xuất chuẩn và đếm tất cả dữ liệu được truyền, lưu trữ số đếm trong một biến môi trường, như:

process_a | count_bytes | process_b

Có ai có một giải pháp gọn gàng hơn?

Câu trả lời:


16

Ống qua dd. đầu vào mặc định của dd là stdin và đầu ra mặc định là stdout; khi nó kết thúc I / O stdin / stdout, nó sẽ báo cáo cho stderr về lượng dữ liệu được truyền.

Nếu bạn muốn nắm bắt đầu ra của dd và các chương trình khác đã nói chuyện với thiết bị lỗi chuẩn, thì hãy sử dụng một mô tả tệp khác. Ví dụ,

$ exec 4>~/fred
$ input-command | dd 2>&4 | output-command
$ exec 4>&-

2
Bạn không thể bỏ qua execvà chỉ xuất ra tệp trực tiếp? input-command | dd 2>~/fred | output-command
Tạm dừng cho đến khi có thông báo mới.

2
À, vâng. Tôi rõ ràng đã có một trong những "khoảnh khắc" đó, xin lỗi.
Phil P

28

Sử dụng pv trình xem ống. Đó là một công cụ tuyệt vời. Một khi bạn biết về nó, bạn sẽ không bao giờ biết bạn đã sống như thế nào nếu không có nó.

Nó cũng có thể hiển thị cho bạn một thanh tiến trình và 'tốc độ' chuyển.


Trong quá trình tìm kiếm của tôi, tôi đã tìm thấy điều này, nhưng tôi cần nó để đặt một biến có số byte được truyền để tôi có thể sử dụng nó trong một quy trình khác.
Simon Hodgson

Ví dụ sử dụng: cat file | pv -bsẽ trả về kích thước của tập tin.
Rodorgas

6

process_a | tee >(process_b) | wc --bytescó thể làm việc. Sau đó, bạn có thể chuyển hướng wcđếm đến bất cứ nơi nào bạn cần. Nếu process_bđầu ra bất cứ điều gì đến stdout/ stderrbạn có thể sẽ cần phải chuyển hướng này đi đâu đó, nếu chỉ /dev/null.

Đối với một ví dụ hơi khó hiểu:

filestore:~# cat document.odt | tee >(dd of=/dev/null 2>/dev/null) | wc --bytes
4295

Bằng cách giải thích: teecho phép bạn xuất trực tiếp ra nhiều tệp (cộng với thiết bị xuất chuẩn) và >()cấu trúc là "thay thế quy trình" của bash, làm cho một quy trình trông giống như một tệp chỉ ghi trong trường hợp này để bạn có thể chuyển hướng đến các quy trình cũng như các tệp ( xem ở đây , hoặc câu hỏi này + câu trả lời cho một ví dụ về việc sử dụng teeđể gửi đầu ra cho nhiều quy trình).


Tôi thích giải pháp này, thật đáng buồn là shelll tôi đang sử dụng (BusyBox) dường như không hỗ trợ ký hiệu> (), nhưng nó cung cấp một cách để thực hiện những gì tôi đang theo đuổi.
Simon Hodgson

Đúng vậy, bạn cần một bash khá hoàn chỉnh để có tính năng đó - đó là loại thứ không được sử dụng phổ biến nên bị loại bỏ các vỏ bị cắt (ngay cả những loại có mục tiêu tương thích nhiều hơn hoặc ít hơn) như busybox để tiết kiệm không gian.
David Spillett

1

Tôi biết tôi đến bữa tiệc muộn, nhưng tôi tin rằng tôi có một câu trả lời tốt có thể tăng cường chủ đề hữu ích này.
Đây là kết hợp của câu trả lời @Phil P và @David Spillett, nhưng:

  • khác với @Phil P, nó tránh tạo một tệp mới
  • khác với @David Spillett, nó duy trì cấu trúc đường ống

Byte-Count được in ra thiết bị xuất chuẩn, cùng với bất kỳ đầu ra nào của process_b.
Bạn có thể sử dụng tiền tố để xác định dòng chứa byte khi làm việc với đầu ra ( Bytes:trong ví dụ).

exec 3>&1
process_a | tee >({ echo -n 'Bytes:'; wc -c; } >&3) | process_b
exec 3>&-

CẢNH BÁO:
Không dựa vào thứ tự của các dòng trong đầu ra
Thứ tự không thể đoán trước và nó luôn có thể khác nhau, ngay cả khi gọi cùng một tập lệnh với cùng tham số!


Đáng buồn thay, nó vẫn chỉ là một cấu trúc bash ...
Mikhail T.
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.