On Thu, 25 Oct 2001, Marc SCHAEFER wrote:

>    tail -f fichier | grep quelque_chose

J'ai oublié de dire que si l'on redirige, il n'y aura pas buffering
ligne-à-ligne, mais avec un plus grand buffer (p.ex. 512 bytes ou plus, je
n'ai pas en tête).

Tout cela c'est la bibliothèque C standard: si stdout est un tty
(terminal), buffering par défaut ligne, sinon `block'. Cf man setvbuf(3)
pour le faire en C.

Exemple:

   xterm_1% cat > abcd
   xterm_2% tail -f /tmp/abcd | grep turlututu > fichier # mode block!
   xterm_3% tail -f fichier

A voir, grep, sauf si connecté à un terminal, fait du buffering plus que
ligne-à-ligne. C'est un comportement qui ne *correspond* pas au
comportement usuel des programmes sous UNIX, qui ne bufférisent pas quand
ils sont face à un pipe, probablement pour optimisation: la preuve c'est
que le tail, lui, passe les données: 

   schaefer@defian:~% ps auxw | grep grep
   schaefer  3670  0.0  0.3  1112  428 pts/7    S    16:22   0:00 grep turlututu
   schaefer@defian:~% strace -p 3670
   read(0, "abcd\n", 32768)                = 5
   read(0, "turlututu\n", 32768)           = 10
   read(0, "turlututu\n", 32768)           = 10

[ tail passe, grep bufférise ]

Symptôme: seulement si on tape énormément dans xterm_1 on a la sortie dans
xterm_3, avec un BUF_SIZE de décalage.

Solution:
  forcer `grep' à changer le buffering, ie passer à ligne-à-ligne, ou
  `no buffering'.

Je l'avoue, je ne sais pas faire, même après un grep rapide dans le manuel
et le info. Et je n'ai pas le temps de RTFS aujourd'hui. Par contre, avec
Perl, si, je sais faire, et comme Perl est un excellent grep:

   #! /usr/bin/perl -w

   use strict;

   $| = 1;  # no buffering

   while (<>) {
      if (/turlututu/) {
         print;
      }
   }

Le seul changement à apporter:

   xterm_2% tail -f /tmp/abcd | ./machin.pl > /tmp/fichier

Je te laisse soin de modifier le programme pour que la regexp soit
passable par argument.

--
http://www-internal.alphanet.ch/linux-leman/ avant de poser
une question. Ouais, pour se désabonner aussi.

Répondre à