Se si desidera solo la prima o la prima riga, il seguente tipo di trucco funziona ed evita i problemi di buffering causati dall'uso di due diversi comandi per leggere il flusso di output:
$ ps -eF | { IFS= read -r x ; echo "$x" ; grep worker; }
$ ls -la / | { IFS= read -r x ; echo "$x" ; grep sbin; }
Il readè incorporato al guscio e non consuma un intero buffer di ingresso solo per uscita una linea, in modo da utilizzare readle foglie tutto il resto dell'output per il comando.
Se vuoi accentuare i problemi di buffering mostrati dai tuoi esempi che usano due diversi comandi, aggiungi sleepa loro per eliminare i problemi di temporizzazione e consenti al comando a sinistra di generare tutto il suo output prima che i comandi a destra provino a leggere uno dei esso:
$ ps -eF | { sleep 5 ; head -n 1 ; grep worker; }
$ ls -la / | { sleep 5 ; head -n 1 ; grep sbin; }
Ora, entrambi gli esempi precedenti falliscono allo stesso modo: headlegge un intero buffer dell'output solo per produrre una riga e quel buffer non è disponibile per quanto segue grep.
Puoi vedere il problema del buffering ancora più chiaramente usando alcuni esempi che numerano le linee di output in modo da poter dire quali righe mancano:
$ ps -eF | cat -n | { sleep 5 ; head -n 1 ; head ; }
$ ls -la /usr/bin | cat -n | { sleep 5 ; head -n 1 ; head ; }
Un modo semplice per visualizzare il problema di buffering è utilizzare seqche genera un elenco di numeri. Possiamo facilmente dire quali numeri mancano:
$ seq 1 100000 | { sleep 5 ; head -n 1 ; head ; }
1
1861
1862
1863
1864
1865
1866
1867
1868
1869
La mia soluzione con i trucchi che utilizza la shell per leggere ed eco la prima riga funziona correttamente anche con il ritardo di sospensione aggiunto:
$ seq 1 100000 | { sleep 5 ; IFS= read -r x ; echo "$x" ; head ; }
1
2
3
4
5
6
7
8
9
10
11
Di seguito è riportato un esempio completo che mostra i headproblemi di buffering, che mostra come
headconsuma un intero buffer dell'output solo per produrre le sue cinque righe ogni volta. Quel buffer consumato non è disponibile per il headcomando successivo
nella sequenza:
$ 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
Guardando il numero 1861sopra, possiamo calcolare la dimensione del buffer utilizzato headcontando l' seqoutput da 1a
1860:
$ seq 1 1860 | wc -c
8193
Vediamo che headè buffering leggendo un intero 8KB (8 * 1024 byte) dell'output di pipe alla volta, anche per produrre solo poche righe del proprio output.
headegrepfare niente.