kontinuierliches Ablesen von Named Pipe (Cat oder Tail -f)

16

Ich habe konfiguriert rsyslog, um bestimmte Protokollereignisse zu protokollieren /dev/xconsole:

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

/dev/xconsoleist eine Named Pipe ( fifo). Wenn ich sehen möchte, was protokolliert wird, kann ich das tun cat /dev/xconsole. Ich bin überrascht zu sehen, dass der Befehl cat /dev/xconsolenach dem Lesen der Datei nicht beendet wird, sondern wie folgt funktioniert tail -f. Mit anderen Worten, die beiden Befehle verhalten sich gleich:

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

Kann mir bitte jemand erklären, warum das so ist?

Gibt es einen Unterschied zwischen den beiden?

Martin Vegter
quelle

Antworten:

18

catliest weiter, bis es EOF wird. Eine Pipe erzeugt am Ausgang nur dann EOF, wenn sie am Eingang EOF erhält. Der Protokollierungsdämon öffnet die Datei, schreibt darauf und hält sie geöffnet - genau wie bei einer regulären Datei -, sodass in der Ausgabe niemals EOF generiert wird. catLies einfach weiter und blockiere, wann immer es erschöpft, was gerade in der Pipe ist.

Sie können dies manuell ausprobieren:

$ mkfifo test
$ cat test

Und in einem anderen Terminal:

$ cat > test
hello

Es wird im anderen Terminal ausgegeben. Dann:

world

Im anderen Terminal wird mehr ausgegeben. Wenn Sie jetzt die Tastenkombination Strg-D drücken, wird auch die andere catbeendet.

In diesem Fall besteht der einzige beobachtbare Unterschied zwischen catund tail -fdarin, ob der Protokollierungsdämon beendet oder neu gestartet wird: catWird dauerhaft angehalten, wenn das schreibende Ende der Pipe geschlossen wird, tail -fbleibt jedoch bestehen (erneutes Öffnen der Datei), wenn der Dämon neu gestartet wird.

Michael Homer
quelle
Entschuldigung, ich sehe nicht, wo "Welt" in Ihrem Beispiel herkommen wird :)
Alexander Mills
Nach Ihrer Eingabe.
Michael Homer
1
Und dann tippst du world, und siehe, "world" erscheint im anderen Terminal.
Michael Homer
2

Es gibt auch einen Unterschied in der Pufferung zwischen catund tail -f. Sie können dies überprüfen:

Pipe erstellen: mkfifo pipe

Beginnen Sie mit dem Lesen der Pipe catim Hintergrund:cat pipe &

Öffne die Pipe und schreibe jede Sekunde darauf: perl -MFcntl -we 'sysopen(my $fh, "pipe", O_WRONLY | O_NONBLOCK); while() {warn "written: " . syswrite($fh, "hello\n"); sleep 1}'

Versuchen Sie dies jetzt mit tail -f pipe &anstelle von cat. Sie können also sehen, dass catZeilen gedruckt werden, sobald sie per Perl-Skript in die Pipe geschrieben wurden, während tail -f sie vor dem Drucken auf stdout auf 4 KB gepuffert werden.

Interessiert an
quelle