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 read
est intégré au shell et ne consomme pas tout un tampon d'entrée juste pour sortir la ligne, donc l'utilisation read
laisse 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 sleep
pour é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 head
lit 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 seq
un 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 head
problèmes de mise en mémoire tampon, montrant comment
head
consomme 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 head
commande 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 1861
ci-dessus, nous pouvons calculer la taille du tampon utilisé head
en comptant la seq
sortie de 1
à
1860
:
$ seq 1 1860 | wc -c
8193
Nous voyons que cela head
met 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.
head
etgrep
ne faites rien là-bas.