dd(1) で空ファイルを作るときは /dev/zero より seek

これ知らない人がけっこういるんだよね...

$ time dd if=/dev/zero of=a.dat bs=1MB count=2K
2048+0 records in
2048+0 records out
2048000000 bytes (2.0 GB) copied, 15.8397 s, 129 MB/s
dd if=/dev/zero of=a.dat bs=1MB count=2K  0.02s user 6.94s system 43% cpu 15.851 total
$ time dd of=b.dat bs=1MB count=0 seek=2K
0+0 records in
0+0 records out
0 bytes (0 B) copied, 5.4887e-05 s, 0.0 kB/s
dd of=b.dat bs=1MB count=0 seek=2K  0.00s user 0.00s system 42% cpu 0.009 total
$ /bin/ls -lsh *.dat
2.0G -rw-rw-r-- 1 nodakai nodakai 2.0G 2011-08-27 17:42 a.dat
   0 -rw-rw-r-- 1 nodakai nodakai 2.0G 2011-08-27 17:43 b.dat
$ df -Th .
Filesystem    Type    Size  Used Avail Use% マウント位置
tmpfs        tmpfs    7.8G  3.9G  3.9G  50% /tmp

あと(上で使ったGNU coreutilsの) man dd には数の指定で M == 1000*1000 や MB == 1024*1024 等suffixを受け付けたり,1024x1024 という計算式まがいが使えるのもきちんと書いてあるが,これも知られてない.Bashの "arithmetic evaluation" $[1024*1024] 等より分かりやすいと思う.
RTFM
(追記: ls -ls-s は,ファイルシステムの言う論理的なファイルサイズのみならず,ブロックデバイス上で占める実サイズをも行頭に表示するという意味.seek 有りで作った方はext4上ではsparse file(疎なファイル)なのでゼロとなっているが,/dev/zero を普通に読んで書いた方は「ゼロというデータ」が連続した実データを実際に2 GB含むことが分かる.余談だが最新のExt4にもXFS等にあった "hole punching" すなわちsparseでないファイルの一部を後からsparseに変える機能が入ったらしい: id:meech:20110727:1311789821 @naota344の今週のLKML)