bacaan berkelanjutan dari pipa bernama (cat atau tail -f)

16

Saya telah mengkonfigurasi rsysloguntuk mencatat peristiwa log tertentu ke /dev/xconsole:

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

/dev/xconsoleadalah pipa bernama ( fifo). Jika saya ingin melihat apa yang sedang dicatat, saya bisa melakukannya cat /dev/xconsole. Saya terkejut melihat, bahwa perintah cat /dev/xconsoletidak selesai setelah membaca file, tetapi bertindak sebagai tail -f. dengan kata lain, kedua perintah berperilaku sama:

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

Adakah yang bisa menjelaskan mengapa itu?

Apakah ada perbedaan di antara keduanya?

Martin Vegter
sumber

Jawaban:

18

catterus membaca sampai mendapat EOF. Sebuah pipa menghasilkan EOF pada output hanya ketika mendapat EOF pada input. Daemon logging sedang membuka file, menulis padanya, dan menjaganya tetap terbuka - seperti halnya file biasa - sehingga EOF tidak pernah dihasilkan pada output. catterus membaca, memblokir kapan saja menghabiskan apa yang ada di dalam pipa.

Anda dapat mencobanya sendiri secara manual:

$ mkfifo test
$ cat test

Dan di terminal lain:

$ cat > test
hello

Akan ada output di terminal lain. Kemudian:

world

Akan ada lebih banyak output di terminal lain. Jika Anda sekarang Ctrl-D input maka yang lain catakan berakhir juga.

Dalam kasus ini, satu-satunya perbedaan yang dapat diamati antara catdan tail -fadalah jika daemon logging diakhiri atau dimulai ulang: catakan berhenti secara permanen ketika ujung tulis dari pipa ditutup, tetapi tail -fakan terus berjalan (membuka kembali file) ketika daemon di-restart.

Michael Homer
sumber
maaf saya tidak melihat dari mana "dunia" akan datang dalam contoh Anda :)
Alexander Mills
Dari ketikan Anda.
Michael Homer
1
Dan kemudian Anda mengetik world , dan, lihat, "dunia" muncul di terminal lain.
Michael Homer
2

Ada juga perbedaan dalam buffering antara catdan tail -f. Anda dapat memeriksa ini:

Buat pipa: mkfifo pipe

Mulai membaca pipa menggunakan catdi latar belakang:cat pipe &

Buka pipa dan tulis padanya setiap detik: perl -MFcntl -we 'sysopen(my $fh, "pipe", O_WRONLY | O_NONBLOCK); while() {warn "written: " . syswrite($fh, "hello\n"); sleep 1}'

Sekarang coba ini dengan tail -f pipe & alih alih cat. Jadi, Anda dapat melihat bahwa catmencetak garis segera setelah ditulis ke pipa dengan skrip perl, sementara tail -f buffer hingga 4 kb sebelum mencetak ke stdout.

Berminat
sumber