đọc liên tục từ ống có tên (mèo hoặc đuôi -f)


16

Tôi đã cấu hình rsyslogđể ghi nhật ký các sự kiện nhật ký nhất định vào /dev/xconsole:

*.*;cron.!=info;mail.!=info      |/dev/xconsole

/dev/xconsolelà một ống có tên ( fifo). Nếu tôi muốn xem những gì đang được đăng nhập, tôi có thể làm cat /dev/xconsole. Tôi ngạc nhiên khi thấy rằng lệnh cat /dev/xconsolekhông hoàn thành sau khi đọc tệp, mà thay vào đó hoạt động như tail -f. nói cách khác, hai lệnh hành xử giống nhau:

cat /dev/xconsole
tail -f /dev/xconsole

Ai đó có thể vui lòng giải thích tại sao lại như vậy không?

Có sự khác biệt nào giữa hai người không?

Câu trả lời:


18

cattiếp tục đọc cho đến khi nó nhận được EOF. Một ống chỉ tạo EOF trên đầu ra khi nó nhận EOF trên đầu vào. Trình nền ghi nhật ký đang mở tệp, ghi vào tệp và giữ cho nó mở - giống như đối với tệp thông thường - vì vậy EOF không bao giờ được tạo trên đầu ra. catchỉ cần đọc, chặn bất cứ khi nào nó làm cạn kiệt những gì hiện có trong đường ống.

Bạn có thể tự mình thử điều này:

$ mkfifo test
$ cat test

Và trong một thiết bị đầu cuối khác:

$ cat > test
hello

Sẽ có đầu ra trong thiết bị đầu cuối khác. Sau đó:

world

Sẽ có nhiều đầu ra trong các thiết bị đầu cuối khác. Nếu bạn bây giờ Ctrl-D đầu vào thì cái khác catcũng sẽ chấm dứt.

Trong trường hợp này, sự khác biệt duy nhất có thể quan sát được giữa cattail -fsẽ là nếu trình nền đăng nhập bị chấm dứt hoặc khởi động lại: catsẽ dừng vĩnh viễn khi kết thúc ghi của đường ống, nhưng tail -fsẽ tiếp tục (mở lại tệp) khi trình nền được khởi động lại.


xin lỗi tôi không thấy "thế giới" sẽ đến từ đâu trong ví dụ của bạn :)
Alexander Mills

Từ việc bạn gõ nó vào.
Michael Homer

1
Và sau đó bạn gõ world, và, lo, "thế giới" xuất hiện trong thiết bị đầu cuối khác.
Michael Homer

2

Cũng có một sự khác biệt trong bộ đệm giữa cattail -f. Bạn có thể kiểm tra điều này:

Tạo đường ống: mkfifo pipe

Bắt đầu đọc ống sử dụng cattrong nền:cat pipe &

Mở ống và viết cho nó mỗi giây: perl -MFcntl -we 'sysopen(my $fh, "pipe", O_WRONLY | O_NONBLOCK); while() {warn "written: " . syswrite($fh, "hello\n"); sleep 1}'

Bây giờ hãy thử điều này với tail -f pipe &thay vì cat. Vì vậy, bạn có thể thấy rằng catin các dòng ngay khi chúng được ghi vào đường ống bằng tập lệnh perl, trong khi tail -f đệm chúng lên đến 4kb trước khi in ra thiết bị xuất chuẩn.


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.