kontinuierliches Lesen aus benannter Pipe (cat oder tail -f)

kontinuierliches Lesen aus benannter Pipe (cat oder tail -f)

Ich habe rsyslogdie Protokollierung bestimmter Protokollereignisse wie folgt konfiguriert /dev/xconsole:

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

/dev/xconsoleist eine benannte Pipe ( fifo). Wenn ich sehen möchte, was protokolliert wird, kann ich tun cat /dev/xconsole. Ich bin überrascht, dass der Befehl cat /dev/xconsolenach dem Lesen der Datei nicht beendet wird, sondern sich wie verhält 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?

Antwort1

catliest weiter, bis es EOF erhält. Eine Pipe erzeugt EOF nur dann am Ausgang, wenn sie EOF am Eingang erhält. Der Logging-Daemon öffnet die Datei, schreibt hinein,und es offen zu halten— genau wie bei einer normalen Datei — daher wird bei der Ausgabe nie ein EOF generiert. Es catliest einfach weiter und blockiert, wenn der aktuelle Inhalt der Pipe erschöpft ist.

Sie können dies selbst manuell ausprobieren:

$ mkfifo test
$ cat test

Und in einem anderen Terminal:

$ cat > test
hello

Im anderen Terminal wird eine Ausgabe angezeigt. Geben Sie dann ein:

world

Es wird seinmehrAusgabe im anderen Terminal. Wenn Sie jetzt Strg-D für die Eingabe drücken, catwird auch das andere Terminal beendet.

In diesem Fall besteht der einzige erkennbare Unterschied zwischen catund tail -fdarin, ob der Protokollierungsdämon beendet oder neu gestartet wird: catwird dauerhaft gestoppt, wenn das Schreibende der Pipe geschlossen wird, tail -fwird aber fortgesetzt (die Datei wird erneut geöffnet), wenn der Daemon neu gestartet wird.

Antwort2

Es gibt auch einen Unterschied inPufferungzwischen catund tail -f. Sie können dies überprüfen:

Rohr erstellen:mkfifo pipe

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

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

Versuchen Sie dies nun mit tail -f pipe &anstelle von cat. Sie sehen also, dass catZeilen gedruckt werden, sobald sie vom Perl-Skript in die Pipe geschrieben werden, während tail -f sie bis zu 4 KB gepuffert werden, bevor sie auf stdout gedruckt werden.

Antwort3

catzeigt Ihnen die gesamte Datei, wenn tail -fnur die letzten Zeilen angezeigt werden und dann. Wenn die Datei also kurz ist, verhalten sie sich gleich, aber wenn die Datei groß ist (100+ Zeilen), können Sie einen deutlichen Unterschied zwischen den beiden sehen.

Zusätzliche Informationen zu diesen Befehlen:

tail http://www.computerhope.com/unix/utail.htm

cat http://www.computerhope.com/unix/ucat.htm

verwandte Informationen