Écriture de la sortie «tail -f» dans un autre fichier

34

Dans la continuité de mon dernier post où j'ai l'habitude grep & tail -fde trouver des occurrences d'événements "rares". Je voudrais enregistrer ceci dans un autre fichier.

J'ai essayé de tourner

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

dans

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

Le fichier est créé, mais rien n'est rempli, est-ce un problème de mise en cache ou autre? Comment puis-je obtenir un ajout en temps réel de la sortie de ma queue à un nouveau fichier?

Mike
la source

Réponses:

44

La mise en mémoire tampon est le problème.

Faites-le de cette façon,

tail -f log.txt | egrep --line-buffered 'WARN | ERROR' | tee filtré_output.txt
# ^^^^^^^^^^^^^^^^

Confirmé de travailler également sur Cygwin.

nik
la source
6

C'est probablement un problème de mise en mémoire tampon. Voir ce message SO sur la désactivation de la mise en mémoire tampon automatique lors de l'utilisation de canaux . Vous pouvez utiliser la unbuffercommande depuis expect:

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

Edit : Étant donné que vous avez un pipeline plus long, vous devez probablement annuler la mise en mémoire tampon de chaque commande (sauf la dernière):

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

Edit 2 : unbufferest disponible sur Cygwin à partir du expectpaquet source (par exemple expect-20030128-1-src.tar.bz2 , trouvé dans le expect/examplesdossier), mais c'est un script très court. Si vous avez expectdéjà installé le paquet, mettez-le simplement dans un script appelé unbufferdans votre /usr/local/binrépertoire:

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

eval spawn -noecho $argv
set timeout -1
expect

Sur Debian, la unbuffercommande est fournie dans le expect-devpaquet et est installée en tant que expect_unbuffer.

Quack Quack
la source
existe-t-il un moyen d'y parvenir avec cygwin?
Mike
ajouté des informations sur l'utilisation dans cygwin; vous aurez besoin du expectpaquet.
Quack Quichotte
Merci, je ne peux pas essayer jusqu'à lundi maintenant malheureusement. Mettra à jour ensuite.
Mike
4

Lorsque vous utilisez une commande qui ne «termine» pas vraiment (comme tail -f), cela ne fonctionne pas vraiment ou si bien (pas du tout).

Vous devriez pouvoir rediriger la sortie vers un fichier texte. Essaye ça:

tail -f log.txt | egrep 'WARN|ERROR' > filtered_output.txt
Josh Hunt
la source
1
Cela ne semble pas fonctionner.
Mike
2

Voici la version unbufferque j'ai:

#!/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
}
En pause jusqu'à nouvel ordre.
la source
+1 merci pour les informations supplémentaires. ne sais pas s'il est compatible avec cygwin mais il ressemble à un script plus intelligent.
Quack Quichote
2

Comme d'autres l'ont souligné, vous pouvez utiliser l' unbufferutilitaire d'Expect.

Notez, cependant, qu'en fonction de votre système et de la version disponible d'Expect, vous devrez peut-être utiliser le -pcommutateur pour annuler la mise en mémoire tampon. Citant la page de manuel:

   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

Vous pourriez donc avoir besoin de cette invocation:

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

BTW, consultez cet article pour une explication approfondie du problème de mise en mémoire tampon de sortie: http://www.pixelbeat.org/programming/stdio_buffering/

Aleksander Adamowski
la source