web-dev-qa-db-fra.com

Pourquoi aucune sortie n'est affichée lors de l'utilisation de grep deux fois?

Fondamentalement, je me demande pourquoi cela ne produit rien:

tail --follow=name file.txt | grep something | grep something_else 

Vous pouvez supposer qu'il devrait produire une sortie J'ai exécuté une autre ligne pour confirmer

cat file.txt | grep something | grep something_else

Il semble que vous ne puissiez pas diriger la sortie de queue plus d'une fois!? Quelqu'un sait-il quel est l'accord et existe-t-il une solution?

EDIT: Pour répondre aux questions jusqu'à présent, le fichier a définitivement un contenu qui devrait être affiché par le grep. Comme preuve si le grep se fait ainsi:

tail --follow=name file.txt | grep something

La sortie s'affiche correctement, mais si elle est utilisée à la place:

tail --follow=name file.txt | grep something | grep something

Aucune sortie n'est affichée.

Si tout est utile, je lance Ubuntu 10.04

41
radman

Vous pouvez également rencontrer un problème avec la mise en mémoire tampon grep à l'intérieur d'un tuyau. c'est-à-dire que vous ne voyez pas la sortie de

   tail --follow=name file.txt | grep something > output.txt

puisque grep mettra en mémoire tampon sa propre sortie.

Utilisez le commutateur --line-buffered pour grep pour contourner ce problème:

tail --follow=name file.txt | grep --line-buffered something > output.txt

Ceci est utile si vous souhaitez obtenir les résultats du suivi dans le fichier output.txt aussi rapidement que possible.

87
simonc

Compris ce qui se passait ici. Il s'avère que la commande fonctionne, c'est juste que la sortie prend beaucoup de temps pour atteindre la console (environ 120 secondes dans mon cas). En effet, le tampon de la sortie standard n'est pas écrit sur chaque ligne mais sur chaque bloc. Donc, au lieu d'obtenir chaque ligne du fichier tel qu'il était en cours d'écriture, j'obtiendrais un bloc géant toutes les 2 minutes environ.

Il convient de noter que cela fonctionne correctement:

tail file.txt | grep something | grep something

Il s'agit du fichier suivant avec --follow=name c'est problématique.

Pour mes besoins, j'ai trouvé un moyen de le contourner, ce que j'avais l'intention de faire était de capturer la sortie du premier grep dans un fichier, de sorte que la commande serait:

tail --follow=name file.txt | grep something > output.txt

Un moyen de contourner cela est d'utiliser la commande script comme ceci:

script -c 'tail --follow=name file.txt | grep something' output.txt

Le script capture la sortie de la commande et l'écrit dans un fichier, évitant ainsi le deuxième canal.

Cela a efficacement contourné le problème pour moi, et j'ai expliqué pourquoi la commande ne fonctionnait pas comme je m'y attendais, problème résolu.

Pour info, ces autres questions de stackoverflow sont liées:
Tromper une application en pensant que son stdin est interactif, pas un tuya
Force la sortie standard d'un autre programme à ne pas être tamponnée en utilisant Python

6
radman