有没有一种方法可以在 linux 中获取 DD 的百分比?

42 linux backup bash command-line dd

这就是正在发生的事情。

我通过 Linux live USB 开始备份我服务器上的驱动器。我开始使用dd命令 vanilla复制第一个驱动器;只是sudo dd if=/dev/sda of=/dev/sdc1然后我记得这只会让控制台空白,直到它完成。

无论如何,我需要对同一个驱动器运行不同的备份,所以我也开始了那个备份sudo dd if=/dev/sdb of=/dev/sdc3 status=progress,然后我得到了一行显示当前传输速率以及以字节为单位的进度的文本。

我希望有一种方法可以显示备份的百分比,而不是计算 1.8TB 中备份了多少字节。有没有比 status=progress 更简单的方法来做到这一点?

Has*_*tur 69

请参阅此问题的答案[ 1 ]

pv

例如,您可以在开始之前使用pv

sudo apt-get install pv    # if you do not have it
pv < /dev/sda > /dev/sc3   # it is reported to be faster
pv /dev/sda > /dev/sc3     # it seems to have the same speed of the previous one
#or 
sudo dd if=/dev/sda | pv -s 1844G | dd of=/dev/sdc3  # Maybe slower 
Run Code Online (Sandbox Code Playgroud)

输出[ 2 ]

440MB 0:00:38 [11.6MB/s] [======>                             ] 21% ETA 0:02:19
Run Code Online (Sandbox Code Playgroud)

注意:
特别是对于大文件,您可能希望查看man dd和设置加速所有硬件所需的选项,例如bs=100M设置缓冲区,oflag=sync计算写入的有效字节数,也许direct......
该选项-s仅采用整数参数1.8T-->1844G
正如您从第一行注意到的那样,您根本不需要dd


kill -USR1 pid

如果您已经启动了该dd命令,一旦您已经个性化了它的 PID(Ctrl- Z+bg并且您阅读了它,或者pgrep ^dd...),您就可以发送一个信号USR1(或SIGUSR1,或SIGINFO见下文)并阅读输出。
如果程序的PID是1234

kill -USR1 1234
Run Code Online (Sandbox Code Playgroud)

dd 将在其 STDERR 的终端上回答类似于

4+1 records in
4+0 records out
41943040 bytes (42 MB) copied, 2.90588 s, 14.4 MB/s
Run Code Online (Sandbox Code Playgroud)

警告:在 OpenBSD 下,您可能需要提前检查kill[ 3 ]的行为:改为使用
kill -SIGINFO 1234
它存在名为 的 sigaction SIGINFO。的SIGUSR1一个,在这种情况下,应终止程序(dd)...
Ubuntu下使用-SIGUSR110)。

  • 您几乎肯定会发现在 dd 命令上使用 'bs' 可以大大加快速度。像 dd if=/dev/blah of=/tmp/blah bs=100M 一次传输 100M 块 (9认同)
  • 很好的答案。但是,我确实要注意,在 OpenBSD 中,正确的终止信号是 SIGINFO,而不是 SIGUSR1。在 OpenBSD 中使用 -USR1 只会杀死 dd。因此,在您在新环境中尝试此操作之前,在您不想中断的传输中,您可能需要熟悉环境的行为(在更安全的测试中)。 (5认同)
  • @Criggie:那可能是因为 `dd` 已经完成了所有的 `write()` 系统调用,并且 `fsync` 或 `close` 被阻塞等待写入到达磁盘。使用慢速 USB 记忆棒时,默认的 Linux I/O 缓冲区阈值会导致脏写入缓冲区的大小与快速磁盘上的大文件在性质上不同,因为缓冲区与您正在复制的内容一样大,并且仍然需要明显的时间。 (3认同)

Mat*_*lia 39

我的这类东西的首选工具是progress

这个工具可以被描述为一个Tiny、Dirty、Linux-and-OSX-Only C 命令,用于查找当前在您的系统上运行的 coreutils 基本命令(cp、mv、dd、tar、gzip/gunzip、cat 等),以及显示复制数据的 百分比。它还可以显示估计的时间吞吐量,并提供“顶级”模式(监控)。

“<code>progress</code> in action”截图

它只是扫描/proc有趣的命令,然后查看目录fdfdinfo查找打开的文件和查找位置,并报告最大文件的状态。

它非常轻巧,几乎与任何命令兼容。

我觉得它特别有用,因为:

  • pvin pipe or相比dcfldd,我不必记住在开始操作时运行不同的命令,我可以事后监控;
  • 与 相比kill -USR1,它几乎适用于任何命令,我不必总是仔细检查联机帮助页以确保我不会意外杀死副本;此外,当不带参数调用时,它会显示当前正在运行的任何常见“数据传输”命令的进度,因此我什至不必查找 PID;
  • 与 相比pv -d,我再次不需要查找 PID。


sle*_*anc 27

运行dd,然后在单独的 shell 中调用以下命令:

pv -d $(pidof dd) # root may be required
Run Code Online (Sandbox Code Playgroud)

这将使 pv 获取dd进程所有打开的文件描述符的统计信息。它将向您显示读取和写入缓冲区所在的位置。

  • 事后有效!?惊人的!! (3认同)
  • 这很酷。它避免了通过 3 个进程实际传输所有数据的内存带宽 + 上下文切换开销!@jpaugh:我想它只是查看`/proc/$PID/fdinfo` 的文件位置,并查看`/proc/$PID/fd` 以查看*哪些*​​ 文件(以及大小)。所以是的,非常酷,而且是一个功能的好主意,但我不会称它为“惊人”,因为有 Linux API 可以让它轮询另一个进程的文件位置。 (3认同)

小智 10

有一个替代方案dddcfldd

dcfldd 是 GNU dd 的增强版本,具有对取证和安全有用的功能。

状态输出 - dcfldd 可以根据传输的数据量和操作需要多长时间向用户更新其进度。

dcfldd if=/dev/zero of=out bs=2G count=1 # test file
dcfldd if=out of=out2 sizeprobe=if
[80% of 2047Mb] 52736 blocks (1648Mb) written. 00:00:01 remaining.
Run Code Online (Sandbox Code Playgroud)

http://dcfldd.sourceforge.net/
https://linux.die.net/man/1/dcfldd


Sir*_*rex 6

作为百分比,您必须做一些数学运算,但是即使在已经开始之后,您也可以通过执行以下操作以人类可读的形式获得 dd 的进度 kill -USR1 $(pidof dd)

当前 dd 进程将显示类似于:

已复制 11117279 字节(11 MB,11 MiB),13.715 秒,811 kB/秒

  • 这基本上与 `status=progress` 给出的相同 (4认同)