GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Machen Sie Tail -f Exit auf einem kaputten Rohr?

Ich möchte eine Datei ansehen, bis etwas Text erscheint

Ich habe diese Antwort gefunden:`tail -f` bis Text gesehen wird

aber als ich es auf Ubuntu ausprobiert habe, wird es nicht beendet:

$ echo one > test.txt
$ echo two >> test.txt
$ echo three >> test.txt
$ echo four >> test.txt
$ cat test.txt | sed '/w/ q'
one
two
$

funktioniert wie erwartet. jedoch, wenn ich versuche, die Datei zu tailsieren

$ tail -f test.txt | sed '/w/ q'
one
two

es geht nie aus. Endstück stoppt nicht, obwohl das Rohr gebrochen ist.

Weiß jemand, wie man tail macht beenden, wenn sed Ausgänge?

Akzeptierte Antwort:

Es sind die gleichen Dinge wie in:

  • Wie kann ich beim Schließen der Pipe vorzeitig aussteigen?
  • Grep langsam zum Beenden, nachdem eine Übereinstimmung gefunden wurde?
  • Finde Ausgabe begrenzen UND Signal 13 vermeiden

In:

cmd1 | cmd2

Ihre Shell wartet zufällig bis cmd1 wird auch nach cmd2 beendet ist bereits beendet. Das ist nicht bei allen Schalen der Fall. Einige wie die Bourne- oder Korn-Shell zum Beispiel nicht.

Wenn cmd2 Stirbt die Pipe auf cmd1 ’s stdout wird kaputt , aber das beendet cmd1 nicht sofort.

cmd1 wird beendet, wenn es das nächste Mal versucht, in diese Pipe zu schreiben. Es erhält dann ein SIGPIPE, dessen Standardaktion darin besteht, den Prozess zu beenden.

Mit cmd1 ==tail -f file und cmd2 ==sed /w/q , tail -f liest die letzten 10 Zeilen der Datei und schreibt sie nach stdout (die Pipe), normalerweise in einem Stück, es sei denn, die Zeilen sind wirklich groß und warten darauf, dass mehr Text an file angehängt wird .

sed , das gleichzeitig ausgeführt wird, wartet auf Eingaben auf seiner stdin, liest sie, verarbeitet sie Zeile für Zeile und beendet sich, wenn es eine Zeile gibt, die w enthält .

Sobald (oder möglicherweise mit einer Verzögerung von einer Zeile mit etwas sed Implementierung), wenn es diese Zeile findet, wird es beendet, aber zu diesem Zeitpunkt tail bereits alles in die Pipe geschrieben hat, was sie schreiben musste, also erhält sie kein SIGPIPE, es sei denn, der Datei wird später zusätzlicher Text hinzugefügt (an diesem Punkt wird sie das fatale write() ausführen ).

Wenn Sie cmd1 wollten zu beenden, sobald cmd2 beendet wird, brauchen Sie etwas, um es einmal zu beenden cmd2 endet. Wie bei:

sh -c 'echo "$$"; exec tail -f test.txt' | {
  IFS= read pid
  sed /w/q
  kill -s PIPE "$pid"
}

Oder mit bash :

{ sed /w/q; kill -s PIPE "$!"; } < <(exec tail -f text.txt)
  

2020 bearbeiten

Wie von @user414777 angemerkt, ist seit Version 8.28 die GNU-Implementierung von tail , im Follow-Modus, fragt jetzt nicht nur nach neuen Daten in der/den Datei(en), die es überwacht, sondern prüft auch, ob seine stdout zu einer kaputten Pipe wird und dann sofort beendet wird (oder innerhalb einer Sekunde, wenn notify wird nicht verwendet), was die obigen Umgehungen überflüssig macht.

Verwandte:Wie verwende ich den Exit-Statuscode?

Beachten Sie jedoch, dass nur GNU tail führt diese Art der Verarbeitung durch, keine andere Implementierung von tail (AFAIK) und kein anderes Dienstprogramm (auch nicht die GNU-Implementierungen).

Also, während:

tail -f file | head -n1

Wird nach einer Zeile beendet,

tail -f file | tr '[:lower:]' '[:upper:]' | head -n1

zum Beispiel nicht unbedingt als tr wird nicht überwachen, ob seine stdout zu einer defekten Pipe wird, und stirbt daher nur, wenn es schreibt etwas dort, nachdem die Pipe wie üblich gebrochen ist (und nur an diesem Punkt wird GNU tail -f wird beendet).


Linux
  1. Wie erstelle ich eine bidirektionale Pipe zwischen zwei Programmen?

  2. Grep und Schwanz -f?

  3. Warum schlägt Rsync mit Broken Pipe (32), Fehler in Socket Io (Code 10) bei Io.c(820) fehl??

  4. So erstellen Sie ein VPN

  5. Wie erhalte ich den Exit-Status eines Shell-Befehls, der in GNU Makefile verwendet wird?

Linux-Tail-Befehl

Rohr B nach D? – A &&B || C | D?

Beheben des Fehlers „Broken Pipe“ mit SSH-Verbindung

EC2 ssh Broken Pipe beendet den laufenden Prozess

Warum bekomme ich cat:Schreibfehler:Rohrbruch selten und nicht immer

Kann ich Qemu mit einem Fehler bei einer Kernel-Panik beenden?