Wenn Sie nur die eine oder andere erste Zeile verwenden möchten, funktioniert der folgende Trick und vermeidet die Pufferungsprobleme, die durch die Verwendung von zwei verschiedenen Befehlen zum Lesen des Ausgabestreams verursacht werden:
$ ps -eF | { IFS= read -r x ; echo "$x" ; grep worker; }
$ ls -la / | { IFS= read -r x ; echo "$x" ; grep sbin; }
Das read
ist in die Shell integriert und verbraucht nicht den gesamten Eingabepuffer, um nur die eine Zeile auszugeben. Wenn Sie also verwenden, read
bleibt der Rest der Ausgabe für den folgenden Befehl übrig.
Wenn Sie die Pufferungsprobleme, die in den Beispielen mit zwei verschiedenen Befehlen gezeigt werden, hervorheben möchten, fügen Sie ein hinzu, um die Zeitprobleme sleep
zu beseitigen, und lassen Sie den Befehl auf der linken Seite alle seine Ausgaben generieren, bevor die Befehle auf der rechten Seite versuchen, einen der Befehle zu lesen es:
$ ps -eF | { sleep 5 ; head -n 1 ; grep worker; }
$ ls -la / | { sleep 5 ; head -n 1 ; grep sbin; }
Nun schlagen beide obigen Beispiele auf die gleiche Weise fehl - der head
liest einen gesamten Puffer der Ausgabe, nur um die eine Zeile zu erzeugen, und dieser Puffer steht den folgenden nicht zur Verfügung grep
.
Sie können das Pufferungsproblem noch deutlicher erkennen, indem Sie einige Beispiele verwenden, die die Ausgabezeilen nummerieren, damit Sie feststellen können, welche Zeilen fehlen:
$ ps -eF | cat -n | { sleep 5 ; head -n 1 ; head ; }
$ ls -la /usr/bin | cat -n | { sleep 5 ; head -n 1 ; head ; }
Eine einfache Möglichkeit, das Pufferungsproblem zu erkennen, besteht darin seq
, eine Liste von Zahlen zu erstellen. Wir können leicht erkennen, welche Zahlen fehlen:
$ seq 1 100000 | { sleep 5 ; head -n 1 ; head ; }
1
1861
1862
1863
1864
1865
1866
1867
1868
1869
Meine Tricklösung mit der Shell zum Lesen und Echo der ersten Zeile funktioniert auch mit der hinzugefügten Schlafverzögerung korrekt:
$ seq 1 100000 | { sleep 5 ; IFS= read -r x ; echo "$x" ; head ; }
1
2
3
4
5
6
7
8
9
10
11
Im Folgenden finden Sie ein vollständiges Beispiel, in dem die head
Pufferungsprobleme dargestellt sind. Es wird gezeigt, wie
head
ein gesamter Puffer der Ausgabe verbraucht wird, um jeweils nur die fünf Zeilen zu erzeugen. Dieser verbrauchte Puffer ist für den nächsten head
Befehl in der Sequenz nicht verfügbar
:
$ 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
Anhand der 1861
obigen Zahl können wir die Größe des verwendeten Puffers berechnen, indem wir head
die seq
Ausgabe von 1
bis zählen
1860
:
$ seq 1 1860 | wc -c
8193
Wir sehen, dass head
das Puffern durch gleichzeitiges Lesen von 8 KB (8 * 1024 Byte) der Pipe-Ausgabe erfolgt, selbst um nur einige Zeilen der eigenen Ausgabe zu erzeugen.
head
undgrep
machen da nichts.