【Linux驱动开发】Linux dd 命令详解

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
相关推荐
律宏阔5 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔5 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴5 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千5 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei375 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei375 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei375 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
GeW5 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux
GeW6 小时前
工业场景中的Linux与数据库选型:高端化转型的技术底座
linux
yunwei376 小时前
eBPF 开发者教程: 简单的 XDP 负载均衡器
linux·后端·性能优化