Se você deseja apenas a primeira linha ou duas, o seguinte tipo de truque funciona e evita os problemas de buffer causados pelo uso de dois comandos diferentes para ler o fluxo de saída:
$ ps -eF | { IFS= read -r x ; echo "$x" ; grep worker; }
$ ls -la / | { IFS= read -r x ; echo "$x" ; grep sbin; }
O read
é incorporado ao shell e não consome um buffer inteiro de entrada apenas para gerar uma linha, portanto, o uso read
deixa todo o restante da saída para o seguinte comando.
Se você deseja acentuar os problemas de buffer mostrados nos seus exemplos que usam dois comandos diferentes, adicione a sleep
a eles para eliminar os problemas de tempo e permita que o comando à esquerda gere toda a sua saída antes que os comandos à direita tentem ler qualquer um dos comandos. isto:
$ ps -eF | { sleep 5 ; head -n 1 ; grep worker; }
$ ls -la / | { sleep 5 ; head -n 1 ; grep sbin; }
Agora, os dois exemplos acima falham da mesma maneira - ele head
lê um buffer inteiro da saída apenas para produzir uma linha e esse buffer não está disponível para o seguinte grep
.
Você pode ver o problema de armazenamento em buffer ainda mais claramente usando alguns exemplos que numeram as linhas de saída, para saber quais linhas estão faltando:
$ ps -eF | cat -n | { sleep 5 ; head -n 1 ; head ; }
$ ls -la /usr/bin | cat -n | { sleep 5 ; head -n 1 ; head ; }
Uma maneira simples de ver o problema do buffer é usar seq
isso gera uma lista de números. Podemos facilmente saber quais números estão faltando:
$ seq 1 100000 | { sleep 5 ; head -n 1 ; head ; }
1
1861
1862
1863
1864
1865
1866
1867
1868
1869
Minha solução de truque usando o shell para ler e ecoar a primeira linha funciona corretamente, mesmo com o atraso do sono adicionado:
$ seq 1 100000 | { sleep 5 ; IFS= read -r x ; echo "$x" ; head ; }
1
2
3
4
5
6
7
8
9
10
11
Abaixo está um exemplo completo mostrando os head
problemas de buffer, mostrando como
head
consome um buffer inteiro da saída apenas para produzir suas cinco linhas por vez. Esse buffer consumido não está disponível para o próximo
head
comando na sequência:
$ 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
Observando o número 1861
acima, podemos calcular o tamanho do buffer usado head
contando a seq
saída de 1
para
1860
:
$ seq 1 1860 | wc -c
8193
Vemos isso em head
buffer lendo 8KB completos (8 * 1024 bytes) da saída do tubo de cada vez, até para produzir apenas algumas linhas de sua própria saída.
head
egrep
não fazer nada lá.