非凡云 发表于 2025-6-5 18:23:53

Linux dd命令详解与使用指南

本帖最后由 非凡云 于 2025-6-5 18:26 编辑

dd 命令是 Linux/Unix 系统中一个功能强大且底层的命令,全称是 Data Duplicator(数据复制器)。它主要用于转换和复制文件,特别擅长处理块设备(如硬盘、分区、USB 驱动器)和原始数据流。核心功能: 从输入文件(if)读取数据,根据指定的转换操作进行处理,然后将结果写入输出文件(of)。重要提示:dd 操作不当极易导致数据永久性丢失! 务必极其谨慎地使用,尤其是在指定输出文件 (of=) 时。确认目标设备或文件是你真正想要覆盖的。
基本语法
dd [选项]...下面是一些常用的 dd 命令选项及其解释:
if=FILE (Input File):


[*]指定输入源。默认为标准输入 (stdin)。
[*]可以是普通文件、块设备文件(如 /dev/sda, /dev/sdb1)、字符设备文件(如 /dev/zero, /dev/random, /dev/null)、管道等。
[*]例子: if=/dev/sda (复制整个硬盘), if=image.iso (读取 ISO 镜像文件)。

of=FILE (Output File):


[*]指定输出目标。默认为标准输出 (stdout)。
[*]可以是普通文件、块设备文件、字符设备文件、管道等。
[*]极其重要: 指定错误的 of=(如你的系统盘)会立即覆盖该设备上的所有数据,导致灾难性后果!三思而后行!
[*]例子: of=/dev/sdb (写入到整个目标硬盘), of=backup.img (创建磁盘镜像文件), of=/dev/null (丢弃数据)。

bs=BYTES (Block Size):


[*]设置一次读取和写入的块大小(以字节为单位)。
[*]对性能有重大影响。较大的 bs 通常能提高吞吐量(减少 I/O 操作次数),但会消耗更多内存。太小的 bs 效率低下;太大的 bs 可能受限于系统资源。
[*]可以使用后缀:c (1 byte), w (2 bytes), b (512 bytes), k (1024 bytes), K (1024 bytes), M (1024*1024 bytes), G (1024*1024*1024 bytes) 等。推荐使用 K, M, G 等大写后缀表示 1024 进制。
[*]例子: bs=4M (使用 4 MiB 的块大小), bs=1K (使用 1 KiB 的块大小), bs=512 (使用 512 字节的块大小 - 传统硬盘扇区大小)。

count=BLOCKS:


[*]指定只复制 BLOCKS 个输入块(块大小由 ibs 或 bs 定义)。
[*]用于限制复制数据的量。
[*]例子: count=1 (复制 1 个块), count=1024 (复制 1024 个块)。

skip=BLOCKS:


[*]在开始读取输入 (if) 之前,跳过开头的 BLOCKS 个块(块大小由 ibs 或 bs 定义)。
[*]用于从输入文件的特定位置开始复制。
[*]例子: skip=1 (跳过第 1 个块)。

seek=BLOCKS:

[*]在开始写入输出 (of) 之前,跳过开头的 BLOCKS 个块(块大小由 obs 或 bs 定义)。
[*]用于从输出文件的特定位置开始写入。
[*]例子: seek=1 (从输出文件的第 2 个块开始写入)。

conv=CONVS (Conversions):


[*]指定一个或多个逗号分隔的转换参数,应用于复制的数据。非常重要!
[*]常用转换:

[*]notrunc:非常重要! 不截断输出文件。仅覆盖写入的部分,保留输出文件中未写入区域的原始内容。在写入文件(而非整个设备)且不想破坏文件原有结构时强烈推荐使用。写入块设备时通常不需要。
[*]noerror:遇到读取错误时继续(而不是停止),通常与 sync 一起使用处理坏块。
[*]sync:用 NUL 字节(或 conv=sync,noerror 时用空格)填充每个输入块到 ibs 大小。常与 noerror 连用以处理读取错误(坏块)。
[*]fsync:在数据传输结束后,强制将输出文件数据写入物理存储(确保数据落盘)。
[*]ascii, ebcdic, ibm:过时的字符集转换,现代系统很少使用。

ibs=BYTES (Input Block Size):


[*]单独设置输入块大小。如果设置了 bs, 则 ibs 和 obs 都被覆盖。
obs=BYTES (Output Block Size):




[*]单独设置输出块大小。如果设置了 bs, 则 ibs 和 obs 都被覆盖。
status=LEVEL (Progress Reporting):


[*]控制输出信息的详细程度(较新的 dd 版本支持)。
[*]none:完全不显示统计信息。
[*]noxfer:不显示最后的传输统计摘要(但显示中间进度)。
[*]progress:最常用! 定期显示传输速率和已传输量(默认行为,通常每秒更新一次)。这是避免 dd 长时间运行无反馈的关键选项。
[*]例子: status=progress

常用示例与场景

复制一个文件到另一个文件:
dd if=/path/to/source/file of=/path/to/destination/file bs=1M

创建一个磁盘镜像:
dd if=/dev/sdx of=/path/to/image/file bs=1M

克隆整个硬盘/分区:
sudo dd if=/dev/sda of=/dev/sdb bs=4M status=progress conv=noerror,sync

[*]将 /dev/sda 的所有内容(包括分区表、引导记录、所有分区数据)原样复制到 /dev/sdb。目标盘 (sdb) 容量必须大于或等于源盘 (sda)。
[*]conv=noerror,sync: 即使源盘有读取错误(坏块)也继续复制,并用 0 填充坏块位置(确保目标盘块对齐)。

创建硬盘/分区的镜像备份文件:
sudo dd if=/dev/sda of=disk_backup.img bs=4M status=progress

[*]将整个 /dev/sda 的内容备份到当前目录下的 disk_backup.img 文件中。需要足够的磁盘空间存放镜像。

从镜像文件恢复到硬盘/分区:
sudo dd if=disk_backup.img of=/dev/sda bs=4M status=progress conv=fsync

[*]将之前备份的镜像文件恢复到 /dev/sda。会完全覆盖目标设备。

测试磁盘读写速度 (粗略):
# 测试写速度 (写入到 /dev/null 最快, 实际写盘更真实)
dd if=/dev/zero of=/tmp/testfile bs=1G count=1 oflag=direct status=progress
# 测试读速度 (从刚写的文件读)
dd if=/tmp/testfile of=/dev/null bs=1G count=1 iflag=direct status=progress

[*]/dev/zero: 提供无限的零字节流。
[*]oflag=direct / iflag=direct: 尝试绕过系统缓存,得到更接近磁盘原始性能的结果(但受系统配置影响)。移除它们会测试带缓存的性能。
[*]注意: /tmp 可能在内存中 (tmpfs),测试的是内存速度。测试真实磁盘应指定挂载点下的文件 (e.g., of=~/testfile)。

创建指定大小的空文件 (用零填充):
dd if=/dev/zero of=largefile.bin bs=1M count=1000

[*]创建一个 1000 MiB (1GiB) 大小的文件 largefile.bin,内容全是零。
[*]比 truncate -s 1G largefile.bin (创建稀疏文件) 更慢,但文件实际占用磁盘空间。

注意:在使用 dd 命令时,要非常小心,因为它可以直接操作磁盘设备,错误的使用可能会破坏数据。dd 命令的输出通常不是很直观,所以在执行过程中可能会看到一些警告信息。为了更好地理解 dd 命令的执行情况,可以使用 status=progress 选项来显示进度。此外,dd 的执行速度可能受到 bs(块大小)和 count(块数量)参数的影响。适当的调整这些参数可以提高数据传输效率。


页: [1]
查看完整版本: Linux dd命令详解与使用指南