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


41

所以这就是正在发生的事情。

我通过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更简单的方法?

Answers:


68

查看此问题的答案[ 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 

输出[ 2 ]

440MB 0:00:38 [11.6MB/s] [======>                             ] 21% ETA 0:02:19

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


kill -USR1 pid

如果您已经启动了该dd命令,则在个性化了其PID(Ctrl- Z+ bg并读取了或pgrep ^dd...)之后,您可以发送信号USR1(或SIGUSR1SIGINFO参见下文)并读取输出。
如果程序的PID为1234

kill -USR1 1234

dd 将在其STDERR的终端上回答类似以下内容

4+1 records in
4+0 records out
41943040 bytes (42 MB) copied, 2.90588 s, 14.4 MB/s

警告:在OpenBSD下,您可能必须事先检查kill[ 3 ]的行为:使用代替
kill -SIGINFO 1234
存在名为的签名SIGINFO。的SIGUSR1一个,在这种情况下,应终止程序(dd)...
Ubuntu下使用-SIGUSR110)。


9
您几乎可以肯定会发现,在dd命令上使用'bs'可以极大地提高它的速度。类似于dd if = / dev / blah of = / tmp / blah bs = 100M一次传输100M块
Sirex '18

1
@Sirex当然,您必须设置bs来优化与硬件有关的传输速率...答案是重复OP的命令行。:-)
Hastur

3
@Criggie:那可能是因为dd已经完成了所有write()系统调用,fsync或者close是因为等待写入磁盘而被阻止。使用慢速USB记忆棒,默认的Linux I / O缓冲区阈值可以确定脏写入缓冲区的大小,从而导致行为与快速磁盘上的大文件相比在性质上有所不同,因为缓冲区的大小与您要复制的缓冲区大小相同仍然需要花费很多时间。
彼得·科德斯

5
好答案。但是,我确实要注意,在OpenBSD中正确的终止信号是SIGINFO,而不是SIGUSR1。在OpenBSD中使用-USR1只会杀死dd。因此,在不希望中断的传输环境中尝试新环境之前,您可能需要熟悉环境的运行方式(在更安全的测试中)。
TOOGAM

1
信号建议dd确实是非常有用的信息,尤其是对于那些您无法/不想安装的服务器pv
Mike

38

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

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

“ <code>进度</ code>实际运行”屏幕截图

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

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

我发现它特别有用,因为:

  • pv在管道或中相比dcfldd,我不必记得在开始操作时要运行其他命令,因此可以监视事实。
  • 与相比kill -USR1,它几乎可以在任何命令上运行,我不必总是仔细检查联机帮助页以确保不会意外杀死该副本。同样,很好的是,当不带参数调用时,它会显示当前正在运行的任何常见“数据传输”命令的进度,因此,我什至不必查找PID;
  • 与相比pv -d,我不需要查找PID。

1
注意:您不仅可以监视coreutils进程,还可以监视更多。只需使用指定命令名称--command <command-name>
jpaugh

1
这太棒了!
Floris

25

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

pv -d $(pidof dd) # root may be required

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


2
事后事实!!惊人!!
jpaugh

3
太酷了。它避免了通过3个进程实际传输所有数据的内存带宽+上下文切换开销!@jpaugh:我想它只是在/proc/$PID/fdinfo查看文件位置,并/proc/$PID/fd查看哪些文件(以及大小)。因此,是的,非常酷,并且是某个功能的好主意,但是我不会称其为“惊人的”,因为有Linux API使它可以轮询另一个进程的文件位置。
彼得·科德斯

@PeterCordes我没有意识到文件位置被内核暴露了。(我一生都在仔细地pv事先准备管道。)当然,一旦我看到这确实可行,我就做很多事情。
jpaugh

9

还有一种替代方法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.

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


它是一个较长的命令名称...很明显,它是劣等的。(+1)
jpaugh

6

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

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

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


4
这基本上是同样的事情status=progress
rakslice

1
我实际上要说的是status = progress完全相同的东西。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.