En prolongement de mon dernier message où j’ai utilisé grep & tail -f
pour rechercher des occurrences d’événements "rares". Je voudrais enregistrer cela 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. S'agit-il d'un problème de mise en cache ou autre? Comment pourrais-je obtenir une annexe en temps réel de la sortie de ma queue dans un nouveau fichier?
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 filter_output.txt # ^^^^^^^^^^^^^^^.
Confirmé de travailler sur Cygwin aussi.
C'est probablement un problème de mise en mémoire tampon. Voir cet article SO pour désactiver la mise en mémoire tampon automatique lors de l'utilisation de canaux . Vous pouvez utiliser la commande unbuffer
à partir de expect
:
$ unbuffer tail -f log.txt | egrep 'WARN|ERROR' | tee filtered_output.txt
Edit : Comme vous avez un pipeline plus long, vous devez probablement annuler chaque tampon (sauf la dernière):
$ unbuffer tail -f log.txt | unbuffer egrep 'WARN|ERROR' | tee filtered_output.txt
Edit 2 : unbuffer
est disponible sur Cygwin à partir du paquet source expect
(par exemple expect-20030128-1-src.tar.bz2 , trouvé dans le dossier expect/examples
), mais c'est un script très court. Si le paquetage expect
est déjà installé, mettez-le simplement dans un script appelé unbuffer
dans votre répertoire /usr/local/bin
:
#!/usr/bin/expect --
# Description: unbuffer stdout of a program
# Author: Don Libes, NIST
eval spawn -noecho $argv
set timeout -1
expect
Sur Debian, la commande unbuffer
est fournie dans le paquet expect-dev
et est installée en tant que expect_unbuffer
.
Lorsque vous utilisez une commande qui ne "termine" pas vraiment (telle que tail -f
), cela ne fonctionne pas vraiment ou très 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
Comme d'autres l'ont déjà souligné, vous pouvez utiliser l'utilitaire unbuffer
de Expect.
Notez cependant que, selon votre système et la version disponible d'Expect, vous devrez peut-être utiliser le commutateur -p
pour annuler la mémoire tampon. Citer 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
Donc, vous pourriez avoir besoin de cette invocation:
unbuffer -p tail -f log.txt | unbuffer -p egrep 'WARN|ERROR' | tee filtered_output.txt
BTW, voir cet article pour une explication détaillée du problème de mise en mémoire tampon de la sortie: http://www.pixelbeat.org/programming/stdio_buffering/
Ceci est la version de unbuffer
que 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
}