问题
在 Linux/Unix 类系统中,dd 命令是一个非常实用的工具,可以用来复制文件、磁盘、分区等。但是 dd 默认在运行时不会显示任何进度信息,这可能会让你感到焦虑和困惑:到底 dd 了多少啊啊啊啊啊。那么,有没有办法让 dd 命令在运行时显示进度呢?
解决方案
dd 命令加上 status=progress 参数
GNU Coreutils 8.24 版本之后,dd 命令增加了一个 status=progress 参数,可以用来显示进度信息。你可以像下面这样使用它:
| |
status=progress 参数会让 dd 命令实时刷新已复制的字节数、耗时和速度,如图:

使用 kill 命令
如果是已经在跑的 dd,也可以用 kill 命令给它发送 USR1 信号。GNU dd 收到这个信号后,会把当前的统计信息打印到标准错误,然后继续运行,不会被终止。我们做一个小实验:
| |
在这个示例中,我们用 dd 从 /dev/zero 设备读取数据并写入 /dev/null 设备,然后用 kill 每隔 1 秒让 dd 输出一次进度信息:
这种方法不需要安装额外的软件,毕竟 kill 是 Linux 系统自带的工具。它也适用于一开始执行 dd 时忘了加 status=progress 参数的情况,可以用这种方法补救:在另一个终端里找到 dd 的进程号再发信号即可。
| |
注意:
USR1打印进度是 GNUdd的行为。macOS/BSD 上的dd不一定支持USR1,发错了可能直接把dd结束掉。那边一般用INFO信号:在运行dd的终端里按Ctrl+T即可。
进度到 100% 了,为什么还没结束?
往 U 盘、SD 卡这类慢速设备写镜像时,经常会看到进度早早就到了总大小,命令却迟迟不退出。这是因为数据先写进了内存里的页缓存,dd 统计的是“写进缓存”的量,真正落盘还需要时间。
可以加上 conv=fsync,让 dd 在退出前等数据真正写入设备;或者加上 oflag=direct 绕过页缓存,让进度更贴近实际写入速度:
| |
/dev/sdX请换成实际的设备名,写错设备会直接覆盖上面的数据,执行前用lsblk再三确认。
总结
| 场景 | 方法 |
|---|---|
新执行的 dd | 加上 status=progress |
| 已经在跑、忘了加参数 | 另开终端 kill -USR1 <PID>(GNU dd) |
macOS/BSD 上的 dd | 按 Ctrl+T 发送 INFO 信号 |
| 写慢速设备 | 再加 conv=fsync,结束时确保数据已落盘 |
以上就是在 Linux/Unix 系统中让 dd 命令显示进度的几种常用方法,你可以根据自己的需求选择合适的方法。