Linux dd 命令详解
概述
dd 是 GNU coreutils 中的一个低级数据复制与转换工具,可在文件、块设备、标准输入/输出之间进行按块拷贝,并提供对读取/写入位置与数据格式的精确控制。它常用于写入镜像到 U 盘、备份/恢复分区或引导记录、按字节或块截取/填充数据、测试磁盘吞吐等。
极度小心:将数据写入错误的设备(例如将镜像写到系统盘)会导致不可恢复的数据丢失。在执行前务必确认设备名(如
lsblk)。
基本语法
dd if=<输入> of=<输出> [bs=<块大小>] [count=<块数>] \
[skip=<跳过块>] [seek=<跳过块>] [status=<模式>] \
[conv=<转换列表>] [iflag=<读标志>] [oflag=<写标志>]
if:输入文件(input file),可为普通文件、设备(/dev/sdX)、或stdin(省略时)。of:输出文件(output file),可为普通文件、设备或stdout(省略时)。bs:同时设置读写块大小,例如bs=1M、bs=4M。支持后缀:K/M/G、KiB/MiB/GiB。count:仅处理指定块数。skip:读取前跳过输入的块数(单位为块)。seek:写入前跳过输出的块数(单位为块)。
若希望以字节为单位控制
skip/seek/count,使用iflag=skip_bytes,count_bytes与oflag=seek_bytes。
重要选项
状态输出
status=progress:显示实时进度与字节数。status=none:安静模式,仅在出错时输出。
转换选项(conv=)
noerror:读错误时继续(默认遇错终止),结合sync使用可保持对齐。sync:对短读进行填充(以 NUL 补齐到块大小)。notrunc:不截断输出文件(默认会截断)。fsync:完成后显式将数据刷写到磁盘。fdatasync:类似fsync,但不强制刷新元数据。sparse:尽可能创建稀疏文件(跳过全零块)。swab、ascii、ebcdic、ibm、block、unblock:字节交换与编码/记录转换(不常用)。
I/O 标志(iflag=/oflag=)
direct:使用直接 I/O,绕过页缓存(对性能与对齐敏感)。sync/dsync:同步写;dsync仅保证数据刷盘。fullblock:读取管道/设备时确保返回完整块大小(常用于stdin)。nonblock:非阻塞 I/O(某些字符设备/管道场景)。seek_bytes/skip_bytes/count_bytes:以字节为单位解释对应参数。
读写块大小(ibs/obs/bs)
ibs:输入块大小;obs:输出块大小;bs同时设置二者。- 大块(如
1M或4M)常能提升吞吐;过大可能使进度刷新不及时或在错误恢复时粒度过粗。
常见用法
将 ISO 写入 U 盘(可启动介质)
sudo dd if=~/Downloads/archlinux.iso of=/dev/sdX bs=4M status=progress conv=fsync
- 将
/dev/sdX替换为目标 U 盘设备(不是分区,如sdX1)。 conv=fsync保证写入完成后数据已落盘。
备份/恢复 MBR(前 512 字节,包括分区表)
# 备份
sudo dd if=/dev/sdX of=~/mbr-backup.bin bs=512 count=1
# 恢复(极度小心)
sudo dd if=~/mbr-backup.bin of=/dev/sdX bs=512 count=1 conv=fsync
备份分区到镜像文件
sudo dd if=/dev/sdX1 of=~/rootfs.img bs=4M status=progress conv=fsync
克隆整盘到另一块盘
sudo dd if=/dev/sdX of=/dev/sdY bs=4M status=progress conv=fsync
- 目标盘
sdY容量应不小于源盘。
仅擦除磁盘的前 1 MiB(清除分区/引导信息)
sudo dd if=/dev/zero of=/dev/sdX bs=1M count=1 conv=fsync
生成测试文件(零/随机)
# 100 MiB 的零填充文件
dd if=/dev/zero of=zero.bin bs=1M count=100 status=progress
# 100 MiB 的随机数据(速度较慢)
dd if=/dev/urandom of=rand.bin bs=1M count=100 status=progress
从镜像中提取区段(以字节控制)
# 从偏移 1 MiB 处开始,复制 10 MiB 到 out.bin
dd if=image.bin of=out.bin iflag=skip_bytes,count_bytes skip=$((1024*1024)) \
count=$((10*1024*1024)) status=progress
校验与验证
-
写入设备后可回读部分或全部数据并计算校验:
写入后对前 100 MiB 回读校验
dd if=/dev/sdX bs=1M count=100 status=none | sha256sum
-
镜像与设备的整盘校验可用:
sha256sum image.bin
回读整盘(耗时):
sudo dd if=/dev/sdX status=none | sha256sum
性能与可靠性建议
- 使用较大的
bs(如1M或4M)提升吞吐;发生错误时需结合noerror,sync以保持偏移对齐。 - 使用
status=progress获取实时进度;批处理或脚本中可用status=none降低日志噪声。 - 需要确保落盘时使用
conv=fsync或在命令后显式调用sync。 oflag=direct可减少缓存污染,但要求块大小与设备对齐,且在某些设备上可能更慢。- 数据恢复场景优先考虑专用工具(如
ddrescue);dd的noerror,sync仅为基本容错。
退出码与错误处理
- 正常完成返回 0;非 0 表示出错。结合
conv=noerror可在读错时继续,但应配合sync以填充对齐。 - 核心错误信息包含读/写的字节数与失败原因;使用
status=progress可观察中途中断位置。
安全注意事项
- 确认目标设备:绝不要将输出指向系统盘或错误的设备。
- 避免对已挂载的文件系统设备直接写入(除非明确知道影响与风险)。
- 使用
sudo执行设备级操作,并在关键步骤前后进行校验与备份。
快速参考
- 基础:
dd if=<in> of=<out> bs=1M status=progress - 仅复制 N 字节:
dd if=<in> of=<out> iflag=count_bytes count=<N> - 跳过/定位(字节):
dd if=<in> of=<out> iflag=skip_bytes oflag=seek_bytes skip=<S> seek=<S> - 容错复制:
dd if=<in> of=<out> bs=1M conv=noerror,sync status=progress - 稀疏输出:
dd if=<in> of=<out> bs=1M conv=sparse