Featured image of post Linux dd 命令在运行时显示进度

Linux dd 命令在运行时显示进度

- 从此不再焦虑到底 dd 了多少

问题

在 Linux/Unix 类系统中,dd 命令是一个非常实用的工具,可以用来复制文件、磁盘、分区等。但是 dd 默认在运行时不会显示任何进度信息,这可能会让你感到焦虑和困惑:到底 dd 了多少啊啊啊啊啊。那么,有没有办法让 dd 命令在运行时显示进度呢?

解决方案

dd 命令加上 status=progress 参数

GNU Coreutils 8.24 版本之后,dd 命令增加了一个 status=progress 参数,可以用来显示进度信息。你可以像下面这样使用它:

1
dd if=/dev/zero of=/dev/null bs=1M count=1000 status=progress

status=progress 参数会让 dd 命令实时刷新已复制的字节数、耗时和速度,如图:

dd status=progress 的输出

使用 kill 命令

如果是已经在跑的 dd,也可以用 kill 命令给它发送 USR1 信号。GNU dd 收到这个信号后,会把当前的统计信息打印到标准错误,然后继续运行,不会被终止。我们做一个小实验:

1
2
3
4
5
6
# 启动 dd 命令,放到后台执行
dd if=/dev/zero of=/dev/null bs=10M count=100000 &
# 获取 dd 命令的进程 ID
PID=$!
# 每隔 1 秒输出一次进度信息
while ps -p $PID > /dev/null; do kill -USR1 $PID; sleep 1; done

在这个示例中,我们用 dd 从 /dev/zero 设备读取数据并写入 /dev/null 设备,然后用 kill 每隔 1 秒让 dd 输出一次进度信息:

kill -USR1 的工作方式

这种方法不需要安装额外的软件,毕竟 kill 是 Linux 系统自带的工具。它也适用于一开始执行 dd 时忘了加 status=progress 参数的情况,可以用这种方法补救:在另一个终端里找到 dd 的进程号再发信号即可。

1
sudo kill -USR1 $(pgrep -x dd)

注意:USR1 打印进度是 GNU dd 的行为。macOS/BSD 上的 dd 不一定支持 USR1,发错了可能直接把 dd 结束掉。那边一般用 INFO 信号:在运行 dd 的终端里按 Ctrl+T 即可。

进度到 100% 了,为什么还没结束?

往 U 盘、SD 卡这类慢速设备写镜像时,经常会看到进度早早就到了总大小,命令却迟迟不退出。这是因为数据先写进了内存里的页缓存,dd 统计的是“写进缓存”的量,真正落盘还需要时间。

进度统计的是写进缓存的量

可以加上 conv=fsync,让 dd 在退出前等数据真正写入设备;或者加上 oflag=direct 绕过页缓存,让进度更贴近实际写入速度:

1
sudo dd if=debian.iso of=/dev/sdX bs=4M status=progress conv=fsync

/dev/sdX 请换成实际的设备名,写错设备会直接覆盖上面的数据,执行前用 lsblk 再三确认。

总结

场景方法
新执行的 dd加上 status=progress
已经在跑、忘了加参数另开终端 kill -USR1 <PID>(GNU dd)
macOS/BSD 上的 dd按 Ctrl+T 发送 INFO 信号
写慢速设备再加 conv=fsync,结束时确保数据已落盘

以上就是在 Linux/Unix 系统中让 dd 命令显示进度的几种常用方法,你可以根据自己的需求选择合适的方法。

参考

转载需要保留原始链接,未经明确许可,禁止商业使用。支持原创 CC BY-NC-SA 4.0
2026-11-01 | 10:00:00 CST
由 Hugo 强力驱动