【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
相关推荐
且从容.3 小时前
Ubuntu安装flume
linux·ubuntu·flume
承渊政道3 小时前
Linux网络学习【Reactor反应堆模式】
linux·网络·学习·ubuntu·reactor
且从容.6 小时前
ubuntu安装flink
linux·ubuntu·flink
爱和冰阔落8 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨8 小时前
WSL2的安装与使用
linux·wsl
微小的鱼8 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng8 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮9 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
Linux-lucky21 小时前
45-Linux学习之旅之防火墙与WEB加固
linux·前端·网络·学习·ubuntu
禁默21 小时前
启元 Q1 二次开发实践:Ubuntu 部署与仿真验证,从 PrimeConsole 到 ROS 2 Humble + RViz
linux·运维·ubuntu