pipe と dd の関係

とある事情で、こんなことがしたくなりました。

pipe を流れてくるデータの先頭 10G バイトのデータだけ取り出したい*1

最初、簡単に次のようなコマンドラインを実行しましたが、これはうまく行きませんでした。

$ gendata | dd ibs=10240k count=1024 | ...

ファイルから直接読み込むときには大きな ibs を指定しても問題がありませんが、pipe ではダメなようです*2。いろいろ試行してみると、ibs が 16K バイト以下ならばブロックが満たされて読み出されるようです。つまり、次のような感じです。

$ gendata | dd ibs=16k count=655360 | ...

これで試したところ、大体はうまくいくのですが、gendata の作りによっては、ibs=16k でも partial read になってしまいます。そこで、今は次のような方法を試しています。なにぶんデータ量が多いので、うまく行っているかどうかまだ分かりません。

$ gendata | dd obs=1024k | dd ibs=1024k count=10240 | ...

ちなみに、この obs をあまり大きくしてもダメなようです。。。

そのほか

ちなみに dd って、count を指定しないで、かつ出力に pipe を繋いだ場合、pipe の出力先が pipe を先に閉じてしまうと record in, record out を表示しないで終了してしまうんですね。知らなかった。以下、例です。

$ cat /dev/zero | dd obs=1024k count=10| od -xv | head  # これは、record in/out を表示します。
$ cat /dev/zero | dd obs=1024k | od -xv | head  # これは、record in/out を表示しません。

*1:count ではなく skip を使う場合は、大丈夫のようです。これは dd のマニュアルにも書いてあります。

*2:partial read になってしまう。