最初の1行または2行だけが必要な場合は、次のタイプのトリックが機能し、2つの異なるコマンドを使用して出力ストリームを読み取ることによるバッファリングの問題を回避します。
$ ps -eF | { IFS= read -r x ; echo "$x" ; grep worker; }
$ ls -la / | { IFS= read -r x ; echo "$x" ; grep sbin; }
read
シェルに内蔵されているので、使用して、ちょうど1出力ラインに入力の全体のバッファを消費しませんread
、次のコマンドの葉に、出力のすべての残りの部分を。
2つの異なるコマンドを使用する例で示されているバッファリングの問題を強調したい場合はsleep
、それらに追加してタイミングの問題を解消し、右側のコマンドがいずれかの読み取りを試みる前に左側のコマンドがすべての出力を生成できるようにしますそれ:
$ ps -eF | { sleep 5 ; head -n 1 ; grep worker; }
$ ls -la / | { sleep 5 ; head -n 1 ; grep sbin; }
さて、上記の例は両方とも同じように失敗しhead
ます-1行を生成するためだけに出力のバッファー全体を読み取り、そのバッファーは以下では使用できませんgrep
。
出力行に番号を付けるいくつかの例を使用すると、バッファリングの問題がさらに明確になり、どの行が欠落しているかがわかります。
$ ps -eF | cat -n | { sleep 5 ; head -n 1 ; head ; }
$ ls -la /usr/bin | cat -n | { sleep 5 ; head -n 1 ; head ; }
バッファリングの問題を確認する簡単な方法は、seq
それを使用して数値のリストを生成することです。欠落している数字は簡単にわかります。
$ seq 1 100000 | { sleep 5 ; head -n 1 ; head ; }
1
1861
1862
1863
1864
1865
1866
1867
1868
1869
シェルを使用して最初の行を読み取り、エコーする私のトリックソリューションは、スリープ遅延を追加しても正しく機能します。
$ seq 1 100000 | { sleep 5 ; IFS= read -r x ; echo "$x" ; head ; }
1
2
3
4
5
6
7
8
9
10
11
以下は、head
バッファリングの問題を示す完全な例で、head
毎回5行を生成するために出力のバッファ全体を消費する方法を示し
ています。その消費されたバッファはhead
、シーケンス内の次のコマンドでは使用できません
。
$ 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
1861
上記の数値を見ると、to
からhead
のseq
出力をカウントすることで、使用されているバッファーのサイズを計算できます:1
1860
$ seq 1 1860 | wc -c
8193
head
パイプライン出力の8KB(8 * 1024バイト)を一度に読み取ってバッファリングしていることがわかります。独自の出力をほんの数行生成することもできます。
head
そしてgrep
そこに何もしません。