次のシェルコマンドは、入力ストリームの奇数行のみを出力するものと想定されていました。
echo -e "aaa\nbbb\nccc\nddd\n" | (while true; do head -n 1; head -n 1 >/dev/null; done)
ただし、代わりに最初の行を出力しますaaa
。
-c
(--bytes
)オプションを使用した場合、同じことは起こりません。
echo 12345678901234567890 | (while true; do head -c 5; head -c 5 >/dev/null; done)
このコマンド1234512345
は期待どおりに出力します。ただし、これはユーティリティのcoreutils実装でのみ機能しhead
ます。busyboxのの出力がちょうどあるので、実装はまだ、余分な文字を食べます12345
。
この特定の実装方法は、最適化のために行われていると思います。行の終わりがわからないため、読む必要がある文字数がわかりません。入力ストリームから余分な文字を消費しない唯一の方法は、バイト単位でストリームを読み取ることです。ただし、一度に1バイトずつストリームから読み取るのは遅い場合があります。したがってhead
、入力ストリームを十分な大きさのバッファに読み込んでから、そのバッファ内の行をカウントすると思います。
--bytes
オプションが使用される場合にも同じことは言えません。この場合、読み取る必要があるバイト数がわかります。したがって、このバイト数を正確に読み取ることができますが、それ以上はできません。corelibsの実装は、この機会を使用しますが、busyboxのの 1にはない、それはまだバッファに必要以上のバイトを読み取ります。おそらく実装を簡素化するために行われます。
質問です。head
ユーティリティが入力ストリームから要求されたより多くの文字を消費することは正しいですか?Unixユーティリティには何らかの標準がありますか?そして、もしあれば、この動作を指定しますか?
PS
を押しCtrl+C
て上記のコマンドを停止する必要があります。Unixユーティリティは、以降の読み取りで失敗しませんEOF
。押したくない場合は、より複雑なコマンドを使用できます。
echo 12345678901234567890 | (while true; do head -c 5; head -c 5 | [ `wc -c` -eq 0 ] && break >/dev/null; done)
単純化のために使用しませんでした。