Impossible de traiter stdout avec une pipe

Je cours tshark sur un fifo, et ce qui suit est un exemple simple d'une boucle qui imprime la sortie de tshark comme il vient :

tshark -i $fifo | while read line; do echo $line done 

Le problème apparaît lorsque j'ajoute des filters à tshark. Cet exemple n'imprime toutes les $line s qu'après la sortie du tshark (l'adresse IP est masquée):

 tshark -i $fifo -T fields -e text -R ' ip.src == **.**.***.** && http.response.code == 200 && http.content_encoding == "gzip" && http.content_type contains "text/html" ' | while read line; do echo $line done 

J'ai essayé sous d'autres forms sans chance:

 while read line; do echo $line done < <(tshark ...) while read line; do echo $line done <<<"$(tshark ...)" 

Même grep imprime les lignes seulement après que tshark se termine:

 tshark ... | grep . 

J'ai essayé de courir tshark sans un tuyau et les lignes sont imprimées correctement comme ils viennent. Pourquoi la command n'est-elle pas alimentée après la sortie du tshark?

Détails supplémentaires: | tee | tee fonctionne, mais je reçois tout imprimé à nouveau quand tshark sort, donc ce n'est pas une bonne affaire.

Vérifiez si votre version de tshark a l'option -l pour la sortie (presque) ligne-tamponnée.

J'ai pu le faire fonctionner avec stdbuf de coreutils. Notez que chaque command après le pipe nécessite que le buffer soit aussi ajusté:

 stdbuf -o 0 tshark -i $fifo -T fields -e text -R ' ip.src == **.**.***.** && http.response.code == 200 && http.content_encoding == "gzip" && http.content_type contains "text/html" ' | stdbuf -o 0 sed 's/\\r\\n,\?/\n/g; s/\\t/\t/g' | 

De la page de manuel:

 `stdbuf': Run a command with modified I/O stream buffering (...) `-o MODE' `--output=MODE' Adjust the standard output stream buffering. 

Certains utilitaires appellent isatty () pour déterminer si leur sortie est un terminal et ajuster leur comportement en conséquence. gzip est un bon exemple de cela.

Essayez de l'exécuter avec le script(1) :

-c, –command

Exécutez la command plutôt qu'un shell interactif. Cela rend facile pour un script de capturer la sortie d'un programme qui se comporte différemment lorsque son stdout n'est pas un tty.

Si vous l'exécutez comme ceci:

 script -c tshark -i $fifo -T fields -e text -R ' ip.src == **.**.***.** && http.response.code == 200 && http.content_encoding == "gzip" && http.content_type contains "text/html" ' | while read line; do echo $line done 

Vous devriez être en mesure de voir les lignes sortir en direct.