简介
dd 命令源自于磁盘复制(disk dump)的缩写,是 Linux 和 Unix 系统中用于转换和复制文件的一个强大工具。它可以在复制过程中进行格式转换,支持不同的块大小,能够直接对硬盘设备进行操作,非常适合进行备份和恢复任务。dd 命令能够精确控制输入/输出过程中的数据块大小以及数量,使其在处理原始磁盘数据时特别有用。
使用方式
bash
dd [选项]
常用选项
-
bs=BYTES
:一次读和写 BYTES 字节。该选项会覆盖ibs
和obs
设定的值,默认为 512。 -
cbs=BYTES
:一次转换 BYTES 字节。 -
conv=CONVS
:指定一个或多个转换参数,以逗号分隔。(具体参数列表见下文) -
count=N
:只拷贝输入文件的前 N 个块。 -
ibs=BYTES
:指定一次读取 BYTES 字节,默认为 512。 -
if=FILE
:从指定的 FILE 中读取而不是默认的标准输入中。 -
iflag=FLAGS
:指定一个或多个输入处理标志,以逗号分隔。(具体标志列表见下文) -
obs=BYTES
:指定一次写入 BYTES 字节,默认为512. -
of=FILE
:将数据写入指定的 FILE 而不是标准输出。 -
oflag=FLAGS
:指定一个或多个输出处理标志,以逗号分隔。(具体标志列表见下文) -
seek=N
:指定在开始写入数据之前应该跳过写入目标的前 N 个块(块大小由obs
指定或默认)。 -
skip=N
:指定在开始处理输入数据之前应该跳过 N 个块(块大小由ibs
指定或默认)。 -
status=LEVEL
:控制dd
命令在标准错误输出(stderr)上打印的信息量级别。none
:抑制所有的输出信息,除了错误消息。noxfer
:抑制最后的传输统计信息。progress
:显示周期性的传输统计信息。
-
--help
:显示帮助信息。 -
--version
:显示版本信息。
CONV 转换参数
-
ascii
:从EBCDIC编码转换为ASCII编码。EBCDIC是一种在IBM大型机上使用的字符编码,而ASCII是更通用的字符编码。 -
ebcdic
:从ASCII编码转换为 EBCDIC 编码。 -
ibm
:从ASCII编码转换到 alternate EBCDIC编码,这种形式常用于IBM系统。 -
block
:将以换行符结尾的记录使用空格填充至指定的cbs
(转换块大小)大小。 -
unblock
:将cbs
大小记录中的尾部空格替换为换行符。 -
lcase
:将大写字母转换为小写字母。 -
ucase
:将小写字母转换为大写字母。 -
sparse
:尝试对包含NUL
(空字符)的输入块进行seek
操作(跳过)而不是写入操作,以此来优化空间使用。 -
swab
:交换每对输入字节的位置。 -
sync
:将每个输入块使用NULs
(空字符)填充至ibs
(输入块大小)。如果与block
或unblock
一起使用,则用空格而不是NULs
填充。 -
excl
:如果输出文件已经存在,操作将失败。 -
nocreat
:不创建输出文件。 -
notrunc
:不截断输出文件,即不改变文件的大小。 -
noerror
:在读取错误后继续运行。 -
fdatasync
:在操作完成前,将数据写入磁盘,确保数据已被真实存储。 -
fsync
:与fdatasync
相似,但也包括元数据的写入。
FLAG
-
append
:以追加模式写入数据到输出文件。(仅对输出有效,建议与conv=notrunc
一起使用以避免截断文件。) -
direct
:使用直接 I/O 进行数据读写,绕过操作系统的缓存,可以提高处理大量数据时的效率。 -
directory
:当目标不是一个目录的时候操作失败。 -
dsync
:使用同步I/O进行数据写入,确保数据在返回之前确实被写入存储设备。 -
sync
:类似于dsync
,但同步操作也包括元数据,确保数据和元数据的完整性。 -
fullblock
:累计完整的输入块,直到达到指定的块大小再处理。(仅适用于输入标志,有助于确保数据块的完整性。) -
nonblock
:使用非阻塞 I/O,允许在没有立即可用数据时继续执行操作,而不是阻塞等待。 -
noatime
:读取文件时不更新其访问时间,有助于减少对源文件系统的影响。 -
nocache
:请求操作系统丢弃或避免使用缓存。 -
noctty
:执行dd
操作时,不将打开的文件分配为控制终端。 -
nofollow
:不跟随符号链接。 -
count_bytes
:将count=N
选项视为字节计数而不是块计数。(仅适用于输入标志。) -
skip_bytes
:将skip=N
选项视为字节计数而不是块计数。(仅适用于输入标志。) -
seek_bytes
:将seek=N
选项视为字节计数而不是块计数。(仅适用于输出标志。)
参考示例
1. 创建一个大小为1GB的文件
bash
dd if=/dev/zero of=1GB.file bs=1G count=1
使用 /dev/zero 作为输入文件(一个提供无限零值的特殊文件),输出到1GB.file,块大小设置为1GB,只复制1个块:
bash
jay@ubuntu:~/Project/test/dd$ dd if=/dev/zero of=1GB.file bs=1G count=1
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 8.12519 s, 132 MB/s
命令执行成功后查看文件属性,确认生成的文件大小为 1G:
bash
jay@ubuntu:~/Project/test/dd$ ls -lh
total 1.1G
-rw-rw-r-- 1 jay jay 1.0G Feb 29 16:52 1GB.file
2. 备份磁盘区
bash
sudo dd if=/dev/sda1 of=./backup.img bs=4M
将 /dev/sda1 分区复制到一个名为 backup.img 的文件中,同时使用 4MB 的块大小提高复制效率。
bash
jay@ubuntu:~/Project/test/dd$ sudo dd if=/dev/sda1 of=./backup.img bs=4M
[sudo] password for jay:
128+0 records in
128+0 records out
536870912 bytes (537 MB, 512 MiB) copied, 0.544554 s, 986 MB/s
3. 生成随机字符串
bash
dd if=/dev/urandom bs=1 count=15 status=none | base64 -w 0
结合 /dev/urandom 设备,我们可以直接生成随机数序列,并且使用 base64 转换为可读字符串:
bash
jay@ubuntu:~/Project/test/dd$ dd if=/dev/urandom bs=1 count=15 status=none | base64 -w 0
AyCv7e1kTuyAVTcnwpvK
示例中使用了抑制输出信息选项来保证输出内容的简洁,并且由于使用了 base64 将二进制数据转换为可读的字符,所以实际长度会比设定的 15 个字节要长,使用 dd 命令生成的二进制数据确实是 15 个字节。
4. 测试磁盘写入速度
bash
dd if=/dev/zero of=./testfile bs=2G count=1 oflag=direct
使用 oflag=direct 可以使写入操作绕过操作系统缓存直接到磁盘,这个方法得到的写入速度更加真实,同时 /dev/zero 是个特殊设备,对它进行读取会产生无限的零值,并且不会产生 IO 操作。因此上述命令只存在写入IO 操作,其结果可以作为磁盘写入速度的依据:
bash
jay@ubuntu:~/Project/test/dd$ dd if=/dev/zero of=./testfile bs=2G count=1 oflag=direct
0+1 records in
0+1 records out
2147479552 bytes (2.1 GB, 2.0 GiB) copied, 2.15183 s, 998 MB/s
5. 测试磁盘读取速度
bash
dd if=./testfile of=/dev/null bs=2G count=1 iflag=direct
同样使用 iflag=direct 可以使读取操作绕过系统缓存,从而得到更真实的读取速度。其中 /dev/null 也是一个特殊设备,所有写入其中的数据都会被丢弃,不会产生 IO 操作,上述命令只存在读 IO 操作,其结果可以作为磁盘读取速度的依据:
bash
jay@ubuntu:~/Project/test/dd$ dd if=./testfile of=/dev/null bs=2G count=1 iflag=direct
0+1 records in
0+1 records out
2147479552 bytes (2.1 GB, 2.0 GiB) copied, 1.34799 s, 1.6 GB/s
注意事项
-
选项参数中的
N
和BYTES
可以带有特定后缀,用来表示不同的数量单位,以字节为基准,以乘法形式与N
或BYTES
进行计算。如c=1
,w=2
,b=512
,kB=1000
,K=1024
,MB=1000*1000
,M=1024*1024
,xM
等同于M
,GB=1000*1000*1000
,G=1024*1024*1024
。以此类推也支持T
,P
,E
,Z
,Y
。 -
当 dd 命令正在执行数据复制或转换操作时,你可以向它发送一个
USR1
信号。接收到这个信号后,dd
进程会将当前的 I/O 统计信息打印到标准错误输出(stderr),然后继续执行其复制或转换操作。这允许用户在dd
操作过程中实时监控其性能和进度,而不会中断或重启命令。 -
使用
dd
命令时需要格外小心,错误的输入文件(if)或输出文件(of)路径可能导致数据丢失。 -
由于
dd
命令非常强大,其能直接作用于物理硬盘,因此建议在执行dd
命令前,再次检查命令的正确性,并确保有适当的数据备份。避免造成无法挽回的后果。