Si vous ne voulez que la première ligne ou deux, le type d'astuce suivant fonctionne et évite les problèmes de mise en mémoire tampon causés par l'utilisation de deux commandes différentes pour lire le flux de sortie:
$ ps -eF | { IFS= read -r x ; echo "$x" ; grep worker; }
$ ls -la / | { IFS= read -r x ; echo "$x" ; grep sbin; }
Le readest intégré au shell et ne consomme pas tout un tampon d'entrée juste pour sortir la ligne, donc l'utilisation readlaisse tout le reste de la sortie pour la commande suivante.
Si vous souhaitez accentuer les problèmes de mise en mémoire tampon illustrés par vos exemples qui utilisent deux commandes différentes, ajoutez-y un sleeppour éliminer les problèmes de synchronisation et autorisez la commande de gauche à générer toutes ses sorties avant que les commandes de droite n'essaient de lire il:
$ ps -eF | { sleep 5 ; head -n 1 ; grep worker; }
$ ls -la / | { sleep 5 ; head -n 1 ; grep sbin; }
Maintenant, les deux exemples ci-dessus échouent de la même manière - le headlit un tampon entier de la sortie juste pour produire la seule ligne, et ce tampon n'est pas disponible pour les suivants grep.
Vous pouvez voir le problème de mise en mémoire tampon encore plus clairement en utilisant quelques exemples qui numérotent les lignes de sortie afin que vous puissiez savoir quelles lignes sont manquantes:
$ ps -eF | cat -n | { sleep 5 ; head -n 1 ; head ; }
$ ls -la /usr/bin | cat -n | { sleep 5 ; head -n 1 ; head ; }
Un moyen simple de voir le problème de mise en mémoire tampon est d'utiliser sequn outil qui génère une liste de nombres. Nous pouvons facilement identifier les numéros manquants:
$ seq 1 100000 | { sleep 5 ; head -n 1 ; head ; }
1
1861
1862
1863
1864
1865
1866
1867
1868
1869
Ma solution astucieuse utilisant le shell pour lire et faire écho à la première ligne fonctionne correctement même avec le retard de sommeil ajouté:
$ seq 1 100000 | { sleep 5 ; IFS= read -r x ; echo "$x" ; head ; }
1
2
3
4
5
6
7
8
9
10
11
Ci-dessous est un exemple complet montrant les headproblèmes de mise en mémoire tampon, montrant comment
headconsomme une mémoire tampon entière de la sortie juste pour produire ses cinq lignes à chaque fois. Ce tampon consommé n'est pas disponible pour la headcommande suivante
de la séquence:
$ seq 1 100000 | { sleep 5 ; head -5 ; head -5 ; head -5 ; head -5 ; }
1
2
3
4
5
1861
1862
1863
1864
499
3500
3501
3502
3503
7
5138
5139
5140
5141
En regardant le nombre 1861ci-dessus, nous pouvons calculer la taille du tampon utilisé headen comptant la seqsortie de 1à
1860:
$ seq 1 1860 | wc -c
8193
Nous voyons que cela headmet en mémoire tampon en lisant un 8 Ko complet (8 * 1024 octets) de la sortie du tuyau à la fois, même pour produire seulement quelques lignes de sa propre sortie.
headetgrepne faites rien là-bas.