Answers:
dd用于将数据块从输入文件复制到输出文件。手册页中的dd块大小选项如下:
ibs=expr
Specify the input block size, in bytes, by expr (default is 512).
obs=expr
Specify the output block size, in bytes, by expr (default is 512).
bs=expr
Set both input and output block sizes to expr bytes, superseding ibs= and obs=.
该dd seek选项类似于UNIX lseek()系统调用1。它在文件内移动读/写指针。从手册页:
seek=n
Skip n blocks (using the specified output block size) from the beginning of the output file before copying.
UNIX中的普通文件具有方便的属性,您不必从头开始读取或写入它们。您可以在任何地方寻找并从那里开始进行读写。因此,bs=4096 seek=7意味着从输出文件的开头移至7 * 4096字节的位置并从此处开始写入。它不会写入文件的0到7 * 4096字节之间的部分。
底层文件系统甚至不会分配根本不会写入的普通文件区域。这些区域称为空洞,文件称为稀疏文件。在您的示例中,file_with_holes开头将有一个7 * 4096字节的孔。(h / t @frostschutz指出dd默认情况下会截断输出文件。)
可以读取这些未分配的区域。你得到一堆零。
[1]在dd编写时,类似系统调用为seek()。
dd if=/dev/zero bs=512 count=2 seek=8388607998 of=/dev/sdddd: /dev/sdd: cannot seek: Invalid argument 0+0 records in 0+0 records out 0 bytes copied, 0.00765396 s, 0.0 kB/s
其他答案解释它了,但如果你有任何疑问,你可以看到什么dd与做strace。
$ strace dd if=/dev/urandom bs=4096 seek=7 count=2 of=file_with_holes
# output is shortened considerably
open("/dev/urandom", O_RDONLY) = 0
open("file_with_holes", O_RDWR|O_CREAT, 0666) = 1
ftruncate(1, 28672) = 0
lseek(1, 28672, SEEK_CUR) = 28672
read(0, "\244\212\222v\25\342\346\226\237\211\23\252\303\360\201\346@\351\6c.HF$Umt\362;E\233\261"..., 4096) = 4096
write(1, "\244\212\222v\25\342\346\226\237\211\23\252\303\360\201\346@\351\6c.HF$Umt\362;E\233\261"..., 4096) = 4096
read(0, "~\212q\224\256\241\277\344V\204\204h\312\25pw9\34\270WM\267\274~\236\313|{\v\6i\22"..., 4096) = 4096
write(1, "~\212q\224\256\241\277\344V\204\204h\312\25pw9\34\270WM\267\274~\236\313|{\v\6i\22"..., 4096) = 4096
close(0) = 0
close(1) = 0
write(2, "2+0 records in\n2+0 records out\n", 312+0 records in
2+0 records out
) = 31
write(2, "8192 bytes (8.2 kB) copied", 268192 bytes (8.2 kB) copied) = 26
write(2, ", 0.00104527 s, 7.8 MB/s\n", 25, 0.00104527 s, 7.8 MB/s
) = 25
+++ exited with 0 +++
它打开/dev/urandom以供读取(if=/dev/urandom),打开file_with_holes以进行创建/写入(of=file_with_holes)。
然后将其截断file_with_holes为4096*7= 28672字节(bs=4096 seek=7)。截断意味着该位置之后的文件内容丢失。(添加conv=notrunc以避免此步骤)。然后,它寻求28672字节。
然后,它从中读取4096字节(bs=4096用作ibs)/dev/urandom,将4096字节(bs=4096用作obs)写入file_with_holes,然后进行另一个读取和写入(count=2)。
然后它关闭/dev/urandom,关闭file_with_holes,并打印,它复制2*4096= 8192字节。最后,它退出而没有错误(0)。
搜寻只会“膨胀”输出文件。Seek = 7表示在输出文件的开头,将插入7个“空”块,其输出块大小= obs = 4096bytes。这是一种快速创建非常大的文件的方法。
obs关联bs,如果不存在,命令将使用bs哪个代替obs。