Si solo desea la primera o dos líneas, el siguiente tipo de truco funciona y evita los problemas de almacenamiento en búfer causados por el uso de dos comandos diferentes para leer la secuencia de salida:
$ ps -eF | { IFS= read -r x ; echo "$x" ; grep worker; }
$ ls -la / | { IFS= read -r x ; echo "$x" ; grep sbin; }
El readestá integrado en el shell y no consume un búfer completo de entrada solo para generar una línea, por lo que el uso readdeja todo el resto de la salida para el siguiente comando.
Si desea acentuar los problemas de almacenamiento en búfer que muestran sus ejemplos que usan dos comandos diferentes, agréguelos sleepa ellos para eliminar los problemas de sincronización y permita que el comando de la izquierda genere toda su salida antes de que los comandos de la derecha intenten leer cualquiera de eso:
$ ps -eF | { sleep 5 ; head -n 1 ; grep worker; }
$ ls -la / | { sleep 5 ; head -n 1 ; grep sbin; }
Ahora, los dos ejemplos anteriores fallan de la misma manera: headlee un búfer completo de la salida solo para producir una línea, y ese búfer no está disponible para lo siguiente grep.
Puede ver el problema del almacenamiento en búfer aún más claramente utilizando algunos ejemplos que numeran las líneas de salida para que pueda saber qué líneas faltan:
$ ps -eF | cat -n | { sleep 5 ; head -n 1 ; head ; }
$ ls -la /usr/bin | cat -n | { sleep 5 ; head -n 1 ; head ; }
Una forma sencilla de ver el problema del almacenamiento en búfer es utilizar sequn generador de una lista de números. Podemos decir fácilmente qué números faltan:
$ seq 1 100000 | { sleep 5 ; head -n 1 ; head ; }
1
1861
1862
1863
1864
1865
1866
1867
1868
1869
Mi solución truco usando el shell para leer y hacer eco de la primera línea funciona correctamente incluso con el retraso de sueño agregado:
$ seq 1 100000 | { sleep 5 ; IFS= read -r x ; echo "$x" ; head ; }
1
2
3
4
5
6
7
8
9
10
11
A continuación se muestra un ejemplo completo que muestra los headproblemas de almacenamiento en búfer, que muestra cómo
headconsume un búfer completo de la salida solo para producir sus cinco líneas cada vez. Ese búfer consumido no está disponible para el siguiente
headcomando en la secuencia:
$ 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
Mirando el número 1861anterior, podemos calcular el tamaño del búfer que se utiliza headcontando la seqsalida de 1a
1860:
$ seq 1 1860 | wc -c
8193
Vemos que headse almacena en búfer leyendo 8 KB completos (8 * 1024 bytes) de la salida de la tubería a la vez, incluso para producir solo unas pocas líneas de su propia salida.
headygrepno hacer nada allí.