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)