Không chặn đệm tên ống?


20

Tôi đang tìm kiếm thứ gì đó mà tôi nghi ngờ không tồn tại: Một ống có tên đệm (fifo) không bị chặn để sử dụng từ dòng lệnh. Có một điều như vậy?

Đây là trường hợp sử dụng: Giả sử tôi có một quy trình sẽ chạy một thời gian dài trong nền và tạo ra rất nhiều đầu ra cho stdout . Tôi không thực sự quan tâm đến đầu ra và không muốn lưu trữ nó (có lẽ tôi không có đủ chỗ để làm), nhưng tôi muốn "thả" theo định kỳ và làm theo những gì nó đang làm, sau đó lại bỏ đi và để nó làm công việc của nó. Vì vậy, tôi muốn chuyển hướng đầu ra của nó sang đường ống có tên đệm, không chặn theo lý thuyết này và sau đó định kỳ chạm vào nó.

Vì vậy, về cơ bản tôi muốn bắt đầu như thế này ( 10Mlà kích thước của bộ đệm):

mkmagicfifo magicfifo 10M
spewingprocess > magicfifo &

... và định kỳ ghé vào để xem chuyện gì đang xảy ra ...

tail -f magicfifo

... mà không magicfifo lưu trữ tất cả đầu ra (vì vậy, không phải là một tệp bình thường) và không có nó chặn quá trình phun ra khi nó đầy và không được gõ (vì vậy, không hoàn toàn là một ống có tên bình thường).

Tôi không nghĩ các giải pháp liên quan tailhoặc prunesẽ làm điều đó (tốt, tôi có thể nghĩ đến một cách giải quyết liên quan tail), bởi vì tailvẫn sẽ yêu cầu tôi lưu trữ tất cả dữ liệu ở đâu đó (nếu tôi muốn thả vào và bỏ qua khi xem nó), và prunephải viết lại tệp, có lẽ (tôi thừa nhận tôi đã không thử / chứng minh điều này) phá vỡ sự chuyển hướng của quá trình tạo ra tất cả đầu ra.

Tôi hy vọng tôi có thể viết một số tiện ích để làm điều này, nhưng * nix có rất nhiều khía cạnh thú vị của các tập tin và đường ống và như vậy, tôi không thể không nghĩ rằng nó tồn tại và tôi chỉ không biết về nó.

Vì vậy: Có một điều như vậy, và nếu vậy nó là gì?


1
Những gì bạn đang mô tả là "bộ đệm vòng" hoặc "bộ đệm tròn". Tôi không biết về bất kỳ công cụ dòng lệnh nào để duy trì một thứ như vậy, mặc dù nó sẽ không quan trọng để tạo ra.
Shawn J. Goff

2
Hãy xem các giải pháp được mô tả trong "fifo không chặn Linux (ghi nhật ký theo yêu cầu)", stackoverflow.com/questions/7360473/ Lỗi .

1
Có vẻ như điều này đã được giải quyết trên StackOverflow: stackoverflow.com/questions/7360473/ mẹo
James Blackburn

@JamesBlackburn: Cảm ơn! Rất thú vị.
TJ Crowder

Câu trả lời:


16

Tôi nghĩ những gì bạn đang tìm kiếm là GNU screen. Nó duy trì bộ đệm để giữ toàn bộ màn hình cuối cùng hoặc hai đầu ra từ một hoặc nhiều chương trình và cho phép bạn ngắt kết nối và quay lại sau.


+1 cho màn hình gợi ý. BTW, bạn có thể định cấu hình nó để chứa nhiều "dòng lịch sử".
Ông Shunz

1
Cảm ơn. Bạn có thể đưa ra một ví dụ về cách bạn áp dụng điều đó cho các lệnh tôi đã trình bày trong câu hỏi của mình không? Trang người đàn ông nói rằng đó là một trình quản lý cửa sổ (tôi nghĩ chúng có nghĩa là theo nghĩa cuối cùng, không phải là ý nghĩa đồ họa, nhưng vẫn còn). Và tôi vẫn có thể thả vào (thông qua ssh) và bỏ học khi cần thiết chứ? (Ví dụ: ops trên các máy chủ từ xa.)
TJ Crowder

Có, bạn có thể sử dụng màn hình GNU theo cách này. Bạn sẽ tạo một phiên mới (có khả năng được đặt tên), chạy lệnh của bạn bên trong phiên đó và sau đó ngắt kết nối.
TML

2
Cũng có tmuxdtach- mọi thứ trong cùng một lớp ứng dụng quản lý phiên / bộ ghép kênh đầu cuối sẽ có thể đạt được điều tương tự.
jw013

5

Bạn có thể sử dụng pv, nó cung cấp nhiều bộ đệm như bạn muốn trong một đường ống dẫn. Bạn có thể sử dụng nó như thế này:

sprewingprocess | pv -B 1g > ordinaryfifo &

Điều đó sẽ cung cấp cho bạn tới 1GB bộ đệm giữa spewingprocessvà fifo. Hầu hết các bản phân phối Linux cung cấp pvtrong một gói được gọi là, tin hay không , pv.


Cảm ơn, nhưng liệu khối đó có bị đầy không nếu tôi không đọc mục tiêu có tên là pipe?
TJ Crowder

1
Vâng, nhưng bạn có sự lựa chọn nào? Trong một vũ trụ hữu hạn, bạn không thể có bộ đệm không giới hạn theo nghĩa đen.
David Schwartz

Sự lựa chọn khác là như tôi mô tả trong câu hỏi của tôi: Không lưu trữ tất cả đầu ra. Khi bộ đệm đầy, những thứ cũ nhất sẽ bị vứt đi.
TJ Crowder

Hmm, tôi đã thử nghiệm điều này và thật không may, nó không hoàn toàn hoạt động. Nếu quá trình đọc fifo dừng đọc một lúc, pv sẽ cố gắng ghi vào fifo và vì nó không đa luồng, điều đó cũng chặn việc đọc dữ liệu vào bộ đệm của pv. Vì vậy, bộ đệm của pv sẽ chỉ tiếp tục lấp đầy trong khi quá trình đọc fifo tiếp tục đọc. pv có thể đọc và đệm một số dữ liệu, nhưng nó không ngăn người viết chặn hoàn toàn.
Daniel S. Sterling

1

Tôi đã từng gặp vấn đề tương tự. Đây là giải pháp đầu tiên của tôi. Đầu tiên ghi đầu ra vào một tệp mà chúng tôi cắt ngắn sau mỗi dòng để nó không tăng trưởng vô thời hạn:

spewingprocess | while read line; do echo $line > buffer.txt ; done

Sau đó đọc từ tệp bằng đuôi (trong đó 2> /dev/nullthoát khỏi thông báo lỗi "tệp bị cắt"):

tail -f ./buffer.txt 2> /dev/null

Bằng cách này, bộ đệm không phát triển và chúng ta có thể ghép kênh, ví dụ như chạy nhiều đuôi như chúng ta muốn. Tuy nhiên, vấn đề với cách tiếp cận này là chúng ta có thể mất dữ liệu khi chúng ta cắt nhanh hơn đuôi có thể đọc được vì thử nghiệm này cho thấy:

for ((i=0; ; i++)) ; do echo "$i" ; done | while read line; do  echo $line > buffer.txt ; done
tail -f ./buffer.txt 2> /dev/null > log.txt

Sau khi chạy một thời gian, dòng đầu tiên và cuối cùng là:

$ head -n 1 log.txt
0
$ tail -n 1 log.txt
78783

Nhưng tệp có ít dòng hơn, vì vậy một số bị mất:

$ wc log.txt
67087  67087 392819 log.txt

Tuy nhiên, đây có vẻ là một giải pháp tốt nếu bạn không quan tâm quá nhiều đến việc mất dữ liệu hoặc khi quá trình phát tán của bạn không đủ nhanh để mất dữ liệu.

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.