基本信息
在Unix上,硬件的设备驱动(如硬盘)和特殊设备文件(如/dev/zero和/dev/random)就像普通文件一样,出现在文件系统中;只要在各自的驱动程序中实现了对应的功能,dd也可以读取自和/或写入到这些文件。这样,dd也可以用在备份硬件的引导扇区、获取一定数量的随机数据等任务中。dd程序也可以在复制时处理数据,例如转换字节序、或在ASCII与EBCDIC编码间互换。
dd的名字可能来源于IBM的工作控制语言(JCL)中的DD语句,意为“Data Description”(数据描述)的缩写。该命令的语句与JCL中的相似,而与其他Unix命令较不同,因此这可能是个玩笑。另一种解释是“cc”(根据命令自身的描述,为“convert and copy”(转换和复制))已经被C语言编译器(C compiler)所占。
dd命令由单一UNIX规范的一部分,IEEE标准1003.1-2008所规定。
用法
dd的命令行语句与其他的Unix程序不同,因为它的命令行选项格式为选项=值,而不是更标准的--选项 值或-选项=值。dd默认从标准输入中读取,并写入到标准输出中,但可以用选项if(input file,输入文件)和of(output file,输出文件)改变。
由于操作系统的不同,用法会有出入。另外,dd的一些特定功能取决于计算机系统的能力,例如直接访问内存。向运行中的dd进程发送SIGINFO信号(Linux上为USR1)可以使它将I/O统计信息打印到标准错误一次,然后继续复制(注意在OS X上,信号可能导致进程终止)。dd可以从键盘中读取标准输入。到达文件结尾时,dd将会退出。信号和EOF是由软件决定。例如,移植到Windows的Unix工具使用不同的EOF:Cygwin使用 (通常的Unix EOF),而MKS工具箱使用(通常的Windows EOF)。
正如Unix哲学一样,dd只做好一件事(并被认为做得“好”)。与复杂的和高度抽象的实用程序不同,除了为不同的选项做底层决定,dd没有其它的算法。一般在每一次运行时,会改变dd的选项以分步处理一个计算机问题。
输出消息
Linux上GNU coreutils提供的变种没有描述运行结束时,dd输出到标准输出消息的格式。然而,其他的实现描述了它,例如BSD上的。
“记录读入”和“记录写出”行显示了已完整传输的块数+不完整的块数,例如物理介质以不完整的块结尾,或是一个物理错误使得一个完整的块无法被读取。
块大小
块是衡量一次读取、写入和转换字节的单位。命令行选项可以为输入/读取(ibs)和输出/写入(obs)指定一个不同的块大小,尽管块大小(bs)选项会覆盖ibs和obs选项。输入和输出的默认块大小为512字节(传统的磁盘块及POSIX规定的“块”大小)复制的count选项、读取的skip选项和写入的seek选项都是以块为单位。转换操作也受“转换块大小”(cbs)影响。
在dd的一些用途中,块大小可能会影响表现。例如,当转换硬盘中数据时,较小的块大小通常会导致更多的字节被转换。发出许多小块的读取是一种开销的浪费,且可能会对执行性能有负面影响。较大的块大小可能会提高复制速度。但是,由于要复制的字节量是由bs×count给出的,因此不可能在一次dd命令中复制素数个字节,除非使用两个糟糕选项之一:bs=N count=1(消耗内存)或bs=1 count=N(大量读请求开销)。替代程序(见下文)允许指定字节,而不是块。在用作网络传输时,根据使用的网络协议,块大小可能会与包大小冲突。
提供给块大小的值会被解释成十进制整数,也可以加入后缀指定倍数。后缀w表示2倍,b表示512倍,k表示1024倍,M表示1024 × 1024倍,G表示1024 × 1024 × 1024倍,等等。另外,在块大小和计数参数中,一些实现也可以使用x表示乘运算。
例如,块大小bs=2x80x18b表示2 × 80 × 18 × 512 = 1474560字节,也就是一张1440 KiB软盘的确切大小。
用途
dd命令可用于各种用途。
数据转换
dd可以在文件、设备、分区和卷之间复制数据。数据可以从其中任何地方输入或输出;但输出到分区时有重要差异。此外在传输过程中,数据可以用conv选项修改以适应介质。
如果最后一个块有意外长度,试图使用cp复制整个磁盘可能会忽略掉它;然而dd却可能成功。源和目标磁盘应该具有相同的大小。
noerror选项意味着如果发生错误,程序也将继续运行。sync选项表示填充每个块到指定字节。
主引导记录
可以修复主引导记录。主引导记录可以转移到文件,或从中转移出来。
要复制软盘的前两个扇区:
dd if=/dev/fd0 of=MBRboot.img bs=512 count=2
要创建整个x86主引导记录的镜像(包括MS-DOS分区表和MBR魔法字节):
dd if=/dev/sda of=MBR.img bs=512 count=1
要创建仅含主引导记录引导代码的镜像(不包括分区表和开机所需的魔法字节):
dd if=/dev/sda of=MBR_boot.img bs=446 count=1
数据修改
dd可以原地修改数据。
用空字节覆盖文件的前512个字节:
dd if=/dev/zero of=path/to/file bs=512 count=1 conv=notrunc
转换选项notrunc意味着不缩减输出文件,也就是说,如果输出文件已经存在,只改变指定的字节,然后退出,并保留输出文件的剩余部分。没有这个选项,dd将创建一个512字节长的文件。
在不同的分区中复制磁盘分区到磁盘映像文件中:
dd if=/dev/sdb2 of=partition.image bs=4096 conv=noerror
磁盘擦除
主条目:数据擦除
出于安全方面的考虑,有时需要擦除丢弃的磁盘。
检查驱动器上是否有数据,并将其输出到标准输出:
dd if=/dev/sda
用零擦除磁盘:
dd if=/dev/zero of=/dev/sda bs=4k
相较于上面数据修改的例子,不需要使用转换选项notrunc,因为当dd的输出文件为块设备时,它没有效果。
bs=4k选项使dd一次读取或写入4千字节。在现代系统中,由于传输容量(如RAID系统),一个更大的块大小可能更有利。注意用随机数据填充磁盘总是比用零慢的多,因为随机数据必须先由CPU和/或HWRNG生成,且不同的设计有不同的性能特点。(后面PRNG的/dev/urandom可能比libc中的要慢。)在大多数较现代的磁盘中,用零擦除会使其中的数据永久丢失。
用零擦除磁盘会使它的数据无法被软件恢复。然而数据仍可能用特殊的实验室技术恢复。
shred程序提供了完成相同任务的替代方法,最后,当前许多Linux发行版还提供了一个精心制作的工具wipe(做得“好”,如上面的Unix哲学),提供了更多方法擦除。
数据恢复
1984年,GNUdd开启了开源软件(OSS)恢复数据、文件、驱动器和分区的历史。dd进程一次处理一个块,它的算法只是在用户界面显示运行状态。1999年10月,一个C语言的程序dd_rescue发布了。它的算法一次能处理两个块。但改进dd_rescue的数据恢复算法、2003年的shell脚本dd_rhelp作者现在推荐GNU ddrescue。它是一个发布于2004年的C++程序,与大多数的Linux发行版一起发行。在开源软件中,GNUddrescue有最先进的块大小变换算法。(ddrescue和dd_rescue尽管名字相近,但却是不同的程序。因为如此,区分更为明确的备用名称也有使用;使用的名称有“addrescue”(freecode.com),“gddrescue”(Debian包名)和“gnu_ddrescue”(openSUSE包名)。)
GNUddrescue既稳定又安全。
另一个开源程序savehd7使用更复杂的算法,但它需要安装自己的语言解释器。
性能基准测试
对驱动器进行基准测试(通常是单线程),使用1024字节块分析连续系统读取和写入的性能:
dd if=/dev/zero bs=1024 count=1000000 of=file_1GBdd if=file_1GB of=/dev/null bs=1024
随机数据生成文件
使用内核随机数驱动,用100个随机字节生成文件:
dd if=/dev/urandom of=myrandom bs=100 count=1
将文件转换为大写
将文件转换为大写:
dd if=filename of=filename1 conv=ucase
创建空文件
创建1GiB的稀疏文件,或增加现有文件的大小:
dd if=/dev/zero of=mytestfile.out bs=1 count=0 seek=1G
(更先进的工具是GNU coreutils中的fallocate或truncate。)
局限
希捷的文档警告说,“一些依赖底层硬盘访问的硬盘工具(如DD)可能不支持48位逻辑区块地址(LBA),除非进行升级”。使用超过128 GiB的ATA硬盘时需要48位LBA。然而在Linux中,dd使用内核读取或写入原始设备文件。2003年释出的2.4.23版本内核已经实现了对48位LBA的支持。
有人开玩笑说,dd意为“destroy disk”(破坏硬盘)或“delete data”(删除数据),因为在对硬盘进行底层操作时,类似颠倒输入和输出文件的一个小错误都可能造成部分或全部硬盘数据的丢失。
dcfldd
dcfldd是dd的一个分支,由前美国国防部计算机取证实验室雇员尼克·哈勃(Nick Harbour)开发的增强版本。与dd相比,dcfldd允许一个以上的输出文件,同时支持多种校验计算方法,还提供了验证模式以匹配文件,并能显示操作进度百分比。
应用实例
1.将本地的/dev/hdb整盘备份到/dev/hdd
dd if=/dev/hdb of=/dev/hdd
2.将/dev/hdb全盘数据备份到指定路径的image文件
dd if=/dev/hdb of=/root/image
3.将备份文件恢复到指定盘
dd if=/root/image of=/dev/hdb
4.备份/dev/hdb全盘数据,并利用gzip工具进行压缩,保存到指定路径
dd if=/dev/hdb | gzip > /root/image.gz
5.将压缩的备份文件恢复到指定盘
gzip -dc /root/image.gz | dd of=/dev/hdb
6.备份磁盘开始的512个字节大小的MBR信息到指定文件
dd if=/dev/hda of=/root/image count=1 bs=512
count=1指仅拷贝一个块;bs=512指块大小为512个字节。
恢复:
dd if=/root/image of=/dev/hda
7.备份软盘
dd if=/dev/fd0 of=disk.img count=1 bs=1440k
(即块大小为1.44M)
8.拷贝内存内容到硬盘
dd if=/dev/mem of=/root/mem.bin bs=1024
(指定块大小为1k)
9.拷贝光盘内容到指定文件夹,并保存为cd.iso文件
dd if=/dev/cdrom(hdc) of=/root/cd.iso
10.增加swap分区文件大小
第一步:创建一个大小为256M的文件:
dd if=/dev/zero of=/swapfile bs=1024 count=262144
第二步:把这个文件变成swap文件:
mkswap /swapfile
第三步:启用这个swap文件:
swapon /swapfile
第四步:编辑/etc/fstab文件,使在每次开机时自动加载swap文件:
/swapfile swap swap defaults 0 0
11.销毁磁盘数据
dd if=/dev/urandom of=/dev/hda1
注意:利用随机的数据填充硬盘,在某些必要的场合可以用来销毁数据。
12.测试硬盘的读写速度
dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file
dd if=/root/1Gb.file bs=64k | dd of=/dev/null
通过以上两个命令输出的命令执行时间,可以计算出硬盘的读、写速度。
13.确定硬盘的最佳块大小:
dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file
dd if=/dev/zero bs=2048 count=500000 of=/root/1Gb.file
dd if=/dev/zero bs=4096 count=250000 of=/root/1Gb.file
dd if=/dev/zero bs=8192 count=125000 of=/root/1Gb.file
通过比较以上命令输出中所显示的命令执行时间,即可确定系统最佳的块大小。
14.修复硬盘
dd if=/dev/sda of=/dev/sda
当硬盘较长时间(比如1,2年)放置不使用后,磁盘上会产生magnetic fluxpoint。当磁头读到这些区域时会遇到困难,并可能导致I/O错误。当这种情况影响到硬盘的第一个扇区时,可能导致硬盘报废。上边的命令有可能使这些数据起死回生。且这个过程是安全,高效的。
15.dd命令做usb启动盘
dd if=xxx.iso of=/dev/sdb bs=1M
root用户或者sudo,用以上命令前必须卸载u盘,sdb是你的u盘,bs=1M是块的大小,后面的数值大,写的速度相对快一点,但也不是无限的,我一般选2M,注意,执行命令后很快完成,但u盘还在闪,等不闪了,安全移除。
命令的解释
定义
dd是Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。
参数