Jeśli chcesz tylko pierwszy wiersz lub dwa, następujący typ lewy działa i pozwala uniknąć problemów z buforowaniem spowodowanych użyciem dwóch różnych poleceń do odczytu strumienia wyjściowego:
$ ps -eF | { IFS= read -r x ; echo "$x" ; grep worker; }
$ ls -la / | { IFS= read -r x ; echo "$x" ; grep sbin; }
Jest read
on wbudowany w powłokę i nie zużywa całego bufora danych wejściowych tylko do wyprowadzenia jednego wiersza, więc użycie read
pozostawia resztę danych wyjściowych dla następującego polecenia.
Jeśli chcesz zaakcentować problemy z buforowaniem pokazane w przykładach, które używają dwóch różnych poleceń, dodaj sleep
je, aby wyeliminować problemy z synchronizacją i pozwól, aby polecenie po lewej stronie wygenerowało wszystkie dane wyjściowe, zanim polecenia po prawej spróbują odczytać dowolne z to:
$ ps -eF | { sleep 5 ; head -n 1 ; grep worker; }
$ ls -la / | { sleep 5 ; head -n 1 ; grep sbin; }
Teraz oba powyższe przykłady zawodzą w ten sam sposób - head
odczytuje cały bufor danych wyjściowych tylko w celu wytworzenia jednej linii, a bufor ten nie jest dostępny dla następujących grep
.
Możesz zobaczyć problem buforowania jeszcze wyraźniej, używając kilku przykładów, które numerują linie wyjściowe, dzięki czemu możesz stwierdzić, które linie brakuje:
$ ps -eF | cat -n | { sleep 5 ; head -n 1 ; head ; }
$ ls -la /usr/bin | cat -n | { sleep 5 ; head -n 1 ; head ; }
Prostym sposobem na dostrzeżenie problemu buforowania jest użycie, seq
która generuje listę liczb. Możemy łatwo stwierdzić, które liczby zaginęły:
$ seq 1 100000 | { sleep 5 ; head -n 1 ; head ; }
1
1861
1862
1863
1864
1865
1866
1867
1868
1869
Moje rozwiązanie polegające na użyciu powłoki do odczytu i echa pierwszego wiersza działa poprawnie nawet po dodaniu opóźnienia uśpienia:
$ seq 1 100000 | { sleep 5 ; IFS= read -r x ; echo "$x" ; head ; }
1
2
3
4
5
6
7
8
9
10
11
Poniżej znajduje się pełny przykład pokazujący head
problemy z buforowaniem, pokazujący, jak
head
zużywa cały bufor danych wyjściowych, aby za każdym razem wygenerować pięć wierszy. Zużyty bufor nie jest dostępny dla następnego
head
polecenia w sekwencji:
$ 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
Patrząc na 1861
powyższą liczbę , możemy obliczyć wielkość używanego bufora, head
zliczając dane seq
wyjściowe od 1
do
1860
:
$ seq 1 1860 | wc -c
8193
Widzimy, że head
buforowanie polega na tym, że jednocześnie odczytuje pełne 8KB (8 * 1024 bajtów) danych wyjściowych potoku, nawet w celu wytworzenia zaledwie kilku wierszy własnych danych wyjściowych.
head
Igrep
zrobić nic tam.