Schreiben der Ausgabe von "tail -f" in eine andere Datei

34

Als Fortsetzung meines letzten Beitrags, in dem ich grep & tail -fVorkommen von "seltenen" Ereignissen gefunden habe. Ich möchte dies in einer anderen Datei aufzeichnen.

Ich habe versucht, mich umzudrehen

tail -f log.txt | egrep 'WARN|ERROR'

in

tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt

Die Datei wird erstellt, aber nichts wird ausgefüllt. Handelt es sich um ein Caching-Problem oder nicht? Wie kann ich die Ausgabe meines Schwanzes in Echtzeit an eine neue Datei anhängen?

Mike
quelle

Antworten:

44

Pufferung ist das Problem.

Mach es so,

tail -f log.txt | egrep --zeilengepuffertes 'WARN | ERROR' | tee filters_output.txt
# ^^^^^^^^^^^^^^^

Bestätigt, auch an Cygwin zu arbeiten.

nik
quelle
6

Es ist wahrscheinlich ein Pufferproblem. Siehe diesen SO-Beitrag zum Deaktivieren der automatischen Pufferung bei Verwendung von Pipes . Sie können den unbufferBefehl verwenden von expect:

$ unbuffer tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt

Bearbeiten : Da Sie eine längere Pipeline haben, müssen Sie wahrscheinlich jeden Befehl (mit Ausnahme des letzten) entpuffern:

$ unbuffer tail -f log.txt | unbuffer egrep 'WARN|ERROR' | tee filtered_output.txt

Edit 2 : unbufferist unter Cygwin im expectQuellcode-Paket verfügbar (z. B. expect-20030128-1-src.tar.bz2 im expect/examplesOrdner), aber es ist ein sehr kurzes Skript. Wenn Sie das expectPaket bereits installiert haben, fügen Sie dies einfach in ein Skript ein, das unbufferin Ihrem /usr/local/binVerzeichnis aufgerufen wird :

#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST

eval spawn -noecho $argv
set timeout -1
expect

Unter Debian ist der unbufferBefehl im expect-devPaket enthalten und wird als installiert expect_unbuffer.

Quacksalber
quelle
Gibt es eine Möglichkeit, dies mit Cygwin zu erreichen?
Mike
Informationen zur Verwendung in Cygwin hinzugefügt; Du brauchst das expectPaket.
Quack Quijote
Danke, kann es leider erst am Montag versuchen. Wird dann updaten.
Mike
4

Wenn Sie einen Befehl verwenden, der nicht wirklich "fertig" ist (wie z. B. tail -f), funktioniert dies nicht wirklich oder gar nicht so gut.

Sie sollten in der Lage sein, die Ausgabe in eine Textdatei umzuleiten. Versuche dies:

tail -f log.txt | egrep 'WARN|ERROR' > filtered_output.txt
Josh Hunt
quelle
1
Das scheint nicht zu funktionieren.
Mike
2

Dies ist die Version unbuffer, die ich habe:

#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST

if {[string compare [lindex $argv 0] "-p"] == 0} {
    # pipeline
    set stty_init "-echo"
    eval spawn -noecho [lrange $argv 1 end]
    close_on_eof -i $user_spawn_id 0
    interact {
    eof {
        # flush remaining output from child
        expect -timeout 1 -re .+
        return
    }
    }
} else {
    set stty_init "-opost"
    set timeout -1
    eval spawn -noecho $argv
    expect
}
Bis auf weiteres angehalten.
quelle
+1 danke für die zusätzlichen Infos. Keine Ahnung, ob es cygwin-freundlich ist, aber wie ein intelligenteres Skript aussieht.
Quack Quijote
2

Wie bereits erwähnt, können Sie das unbufferDienstprogramm von Expect verwenden.

Beachten Sie jedoch, dass Sie abhängig von Ihrem System und der verfügbaren Version von Expect möglicherweise den -pSchalter zum Entpuffern verwenden müssen. Zitieren der Manpage:

   Normally, unbuffer does not read from stdin.  This simplifies use of unbuffer in some situations.  To use unbuffer in a  pipeline,  use
   the -p flag.  Example:

           process1 | unbuffer -p process2 | process3

Möglicherweise benötigen Sie diesen Aufruf:

unbuffer -p tail -f log.txt | unbuffer -p egrep 'WARN|ERROR' | tee filtered_output.txt

Übrigens finden Sie in diesem Artikel eine ausführliche Erläuterung des Problems der Ausgabepufferung: http://www.pixelbeat.org/programming/stdio_buffering/

Aleksander Adamowski
quelle