dd (Unix)

Unix與類Unix作業系統上的指令

dd是一个Unix类Unix系统上的命令,主要功能为转换和复制文件。[1]

在Unix上,硬件的设备驱动(如硬盘)和特殊设备文件(如/dev/zero/dev/random)就像普通文件一样,出现在文件系统中;只要在各自的驱动程序中实现了对应的功能,dd也可以读取自和/或写入到这些文件。这样,dd也可以用在备份硬件的引导扇区、获取一定数量的随机数据等任务中。dd程序也可以在复制时处理数据,例如转换字节序、或在ASCIIEBCDIC编码间互换。[2]

dd的名字可能来源于IBM工作控制语言(JCL)中的DD语句,[3]意为“Data Description”(数据描述)的缩写。[4]该命令的语句与JCL中的相似,而与其他Unix命令较不同,因此这可能是个玩笑。[3]另一种解释是“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使用<ctrl-d> (通常的Unix EOF),而MKS工具箱使用<ctrl-z>(通常的Windows EOF)。

正如Unix哲学一样,dd只做好一件事(并被认为做得“好”)。与复杂的和高度抽象的实用程序不同,除了为不同的选项做底层决定,dd没有其它的算法。一般在每一次运行时,会改变dd的选项以分步处理一个计算机问题。

输出消息

编辑

Linux上GNU coreutils提供的变种没有描述运行结束时,dd输出到标准输出消息的格式。然而,其他的实现描述了它,例如BSD上的。

“记录读入”和“记录写出”行显示了已完整传输的块数+不完整的块数,例如物理介质以不完整的块结尾,或是一个物理错误使得一个完整的块无法被读取。

块大小

编辑

是衡量一次读取、写入和转换字节的单位。命令行选项可以为输入/读取(ibs)和输出/写入(obs)指定一个不同的块大小,尽管块大小(bs)选项会覆盖ibsobs选项。输入和输出的默认块大小为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却可能成功。源和目标磁盘应该具有相同的大小。

不同情况的dd格式
dd if=/dev/sr0 of=myCD.iso bs=2048 conv=noerror,sync 从CD-ROM中创建ISO磁盘镜像
dd if=/dev/sda2 of=/dev/sdb2 bs=4096 conv=noerror 克隆一个分区到另一个。
dd if=/dev/ad0 of=/dev/ad1 bs=1M conv=noerror 克隆硬盘“ad0”到“ad1”。

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的输出文件为块设备时,它没有效果。[5]

bs=4k选项使dd一次读取或写入4千字节。在现代系统中,由于传输容量(如RAID系统),一个更大的块大小可能更有利。注意用随机数据填充磁盘总是比用零慢的多,因为随机数据必须先由CPU和/或HWRNG生成,且不同的设计有不同的性能特点。(后面PRNG的/dev/urandom可能比libc中的要慢。)在大多数较现代的磁盘中,用零擦除会使其中的数据永久丢失。[6]

用零擦除磁盘会使它的数据无法被软件恢复。然而数据仍可能用特殊的实验室技术恢复。

shred程序提供了完成相同任务的替代方法,最后,目前许多Linux发行版还提供了一个精心制作的工具wipe[7](做得“好”,如上面的Unix哲学),提供了更多方法擦除。

数据恢复

编辑

1984年,GNU dd开启了开源软件(OSS)恢复数据、文件、驱动器和分区的历史。dd进程一次处理一个块,它的算法只是在用户界面显示运行状态。1999年10月,一个C语言的程序dd_rescue发布了。它的算法一次能处理两个块。但改进dd_rescue的数据恢复算法、2003年的shell脚本dd_rhelp作者现在推荐GNU ddrescue[8]它是一个发布于2004年的C++程序,与大多数的Linux发行版一起发行。在开源软件中,GNU ddrescue有最先进的块大小变换算法。[9]ddrescuedd_rescue尽管名字相近,但却是不同的程序。因为如此,区分更为明确的备用名称也有使用;使用的名称有“addrescue”(freecode.com),“gddrescue”(Debian包名)和“gnu_ddrescue”(openSUSE包名)。)

GNU ddrescue既稳定又安全。[10]

另一个开源程序savehd7使用更复杂的算法,但它需要安装自己的语言解释器。

驱动器性能基准测试

编辑

对驱动器进行基准测试(通常是单线程),使用1024字节块分析连续系统读取和写入的性能:

dd if=/dev/zero bs=1024 count=1000000 of=file_1GB
dd 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中的fallocatetruncate。)

局限

编辑

希捷的文档警告说,“一些依赖底层硬盘访问的硬盘工具(如DD)可能不支持48位逻辑区块地址(LBA),除非进行升级”。[11]使用超过128 GiB的ATA硬盘时需要48位LBA。然而在Linux中,dd使用内核读取或写入原始设备文件[a]2003年释出的2.4.23版本内核已经实现了对48位LBA的支持。[12][13]

有人开玩笑说,dd意为“destroy disk”(破坏硬盘)或“delete data”(删除数据),因为在对硬盘进行底层操作时,类似颠倒输入和输出文件的一个小错误都可能造成部分或全部硬盘数据的丢失。[2]

dcfldd

编辑

dcfldddd的一个分支,由前美国国防部计算机取证实验室雇员尼克·哈勃(Nick Harbour)开发的增强版本。[14][15][16]dd相比,dcfldd允许一个以上的输出文件,同时支持多种校验计算方法,还提供了验证模式以匹配文件,并能显示操作进度百分比。

参见

编辑

注释

编辑
  1. ^ 这可以用strace检查。

参考文献

编辑
  1. ^ Bell Laboratories. dd man page. [2009-02-25]. (原始内容存档于2011-02-08). 
  2. ^ 2.0 2.1 Sam Chessman. How and when to use the dd command?. CodeCoffee. [2008-02-19]. (原始内容存档于2008-02-14). 
  3. ^ 3.0 3.1 Eric S. Raymond. dd. [2008-02-19]. (原始内容存档于2018-12-13). 
  4. ^ 参见旧讨论The Unix "dd" command. alt.folklore.computers. [2011-07-05]. (原始内容存档于2011-07-09). 
  5. ^ linux - Why using conv=notrunc when cloning a disk with dd?. Stack Overflow. 2013-12-11 [2014-03-24]. (原始内容存档于2014-03-24). 
  6. ^ Wright, Craig; Kleiman, Dave; Sundhar R.S., Shyaam. Overwriting Hard Drive Data: The Great Wiping Controversy. Lecture Notes in Computer Science. Information Systems Security. 2008, 5352: 243–257 [2012-03-07]. doi:10.1007/978-3-540-89862-7_21. (原始内容存档于2019-09-24). 
  7. ^ Wipe: Secure File Deletion. Wipe.sf.net. [2014-03-24]. 
  8. ^ LAB Valentin. dd_rhelp author's repository. 2011-09-19 [2013-04-20]. (原始内容存档于2008-05-16). Important note : For some times, dd_rhelp was the only tool (AFAIK) that did this type of job, but since a few years, it is not true anymore: Antonio Diaz did write a ideal replacement for my tool: GNU 'ddrescue'. 
  9. ^ Damaged Hard Disk. www.cgsecurity.org. [2008-05-20]. (原始内容存档于2008-05-10). 
  10. ^ Interview with GNU ddrescue's Antonio Diaz Diaz. Blue-GNU. [2008-12-06]. (原始内容存档于2008-04-15). 
  11. ^ Windows 137GB (128 GiB) Capacity Barrier - Seagate Technology (March 2003)
  12. ^ ChangeLog-2.4.23. www.kernel.org. [2009-12-07]. (原始内容存档于2009-10-08). 
  13. ^ Linux-2.4.23 released Archive.is存档,存档日期2012-12-14 Linux kernel mailing list, 2003.
  14. ^ DCFLDD at Source Forge. Source Forge. [2013-08-17]. (原始内容存档于2013-08-02). 
  15. ^ Jeremy Faircloth, Chris Hurley. Penetration Tester's Open Source Toolkit. Syngress. 2007: 470 – 472. ISBN 9780080556079. 
  16. ^ Jack Wiles, Anthony Reyes. The Best Damn Cybercrime and Digital Forensics Book Period. Syngress. 2011: 408 – 411. ISBN 9780080556086. 

外部链接

编辑