你如何监控dd的进度?

dd是一个奇迹。 它允许您将硬盘驱动器复制到另一个硬盘驱动器,完全归零硬盘驱动器等。但是一旦启动dd命令,没有什么可以告诉您它的进度。 它只是坐在光标处,直到命令最终完成。 那么如何监控dd的进展呢?

更新2016 :如果您使用GNU coreutils> = 8.24(默认情况下在Ubuntu Xenial 16.04中),请参阅下面的方法2以获取显示进度的替代方法。


方法1:通过使用pv

安装pv并将其放在仅输入/输出dd命令之间。

注意 :您已经开始使用dd时无法使用它。

从包装说明 :

pv – Pipe Viewer – 是一个基于终端的工具,用于监控通过管道的数据进度。 它可以插入到两个进程之间的任何正常管道中,以直观地指示数据通过的速度,采取的时间,接近完成的时间以及估计完成之前的时间。

安装

 sudo apt-get install pv 

 dd if=/dev/urandom | pv | dd of=/dev/null 

产量

 1,74MB 0:00:09 [ 198kB/s] [ <=> ] 

如果您想要时间估算,可以使用--size指定近似大小。


示例假设从/ dev / sdb复制了2GB磁盘

没有pv命令是:

 sudo dd if=/dev/sdb of=DriveCopy1.dd bs=4096 

pv命令:

 sudo dd if=/dev/sdb | pv -s 2G | dd of=DriveCopy1.dd bs=4096 

输出:

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

其他用途

您当然可以直接使用pv将输出传递给stdout:

 pv /home/user/bigfile.iso | md5sum 

产量

 50,2MB 0:00:06 [8,66MB/s] [=======> ] 49% ETA 0:00:06 

请注意,在这种情况下, pv自动识别大小。


方法2:添加到ddstatus选项(GNU Coreutils 8.24+)

GNU Coreutils 8.24+(Ubuntu 16.04及更新版本)中的dd获得了一个新status选项来显示进度:

 dd if=/dev/urandom of=/dev/null status=progress 

产量

 462858752 bytes (463 MB, 441 MiB) copied, 38 s, 12,2 MB/s 

从HowTo:监控dd的进度

您可以使用kill命令监视dd的进度而不停止它。

要查看dd运行后的进度,请打开另一个终端并输入:

 sudo kill -USR1 $(pgrep ^dd) 

这将在dd终端窗口中显示dd进度而不会暂停进程。 如果您使用的是BSD或OS X,请使用INFO而不是USR1USR1信号将终止dd。

如果您想定期更新dd进度,请输入:

 watch -n5 'sudo kill -USR1 $(pgrep ^dd)' 

watch会每隔n秒( -n5 = 5秒)探测dd进程并报告而不会停止它。

请注意上面命令中的正确单引号。

一些方便的样本使用与pv和更少的打字或更多的进展,然后其他答案:

首先,您需要使用以下命令安装pv

 sudo apt-get install pv 

然后一些例子是:

 pv -n /dev/urandom | dd of=/dev/null pv -tpreb source.iso | dd of=/dev/BLABLA bs=4096 conv=notrunc,noerror 

注意:第一个样本少于5个字符,然后输入dd if=/dev/urandom | pv | dd of=/dev/null dd if=/dev/urandom | pv | dd of=/dev/null dd if=/dev/urandom | pv | dd of=/dev/null

我最喜欢克隆磁盘驱动器:

 (pv -n /dev/sda | dd of=/dev/sdb bs=128M conv=notrunc,noerror) 2>&1 | dialog --gauge "Running dd command (cloning), please wait..." 10 70 0 

截图

来源: http : //www.cyberciti.biz/faq/linux-unix-dd-command-show-progress-while-coping/

也用于归档自己。

dd运行时使用Ctrl + Shift + T ,它将输出进度(以字节为单位):

 load: 1.51 cmd: dd 31215 uninterruptible 0.28u 3.67s 321121+0 records in 321120+0 records out 164413440 bytes transferred in 112.708791 secs (1458745 bytes/sec) 

为了完整起见:

GNU coreutils的 8.24版本包含一个dd补丁,用于引入打印进度的参数。

引入此更改的提交有以下评论:

dd:新状态=定期打印统计信息的进度级别

许多发行版,包括Ubuntu 16.04.2 LTS都使用这个版本。

最好的是使用http://dcfldd.sourceforge.net/,它很容易通过apt-get安装

原生进度状态被添加到dd !!!

新版Coreutils(8.24)为dd工具添加了进度状态:

在Xubuntu 15.10上的用法:

打开终端并键入以下命令:

 wget ftp://ftp.gnu.org/pub/gnu/coreutils/coreutils-8.24.tar.xz tar -xf coreutils-8.24.tar.xz cd coreutils-8.24 ./configure && make -j $(nproc) 

以root身份运行dd

 sudo su cd src ./dd if=/dev/sdc of=/dev/sda conv=noerror status=progress 

您将看到:字节,秒和速度(字节/秒)。

要检查dd的版本:

本机:

 dd --version 

新:

 cd coreutils-8.24/src ./dd --version 

如果您已经启动了dd,并且正在编写文件,例如在创建pendrive到磁盘的副本时,可以使用watch命令不断观察输出文件的大小以查看更改并估计完成情况。

 watch ls -l /pathtofile/filename 

仅查看文件大小(h-human view):

 watch ls -sh /pathtofile/filename 

dd | pv | dd dd | pv | dd dd | pv | dd triad让我的50GB vm拷贝需要800秒,而不是使用dd的260秒。 有了这个管道,至少,pv不知道输入文件有多大,所以它无法告诉你你有多远,所以没有不好的做法如下 – 并且你获得了一个很好的速度优势:

我会避免任何大的pv,(如果使用Bash):

控制-D dd过程

bg把它放在后台。 观察到bg将为您提供类似[1] 6011输出,其中后一个数字是进程ID。 所以,做:

while true; do kill -USR1 process_id ; sleep 5; done

其中process_id是您观察到的进程ID。 当您看到以下内容时,按下Control-C:

 [1]+ Done dd if=/path/file.qcow2 of=/dev/kvm/pxetest bs=4194304 conv=sparse -bash: kill: (60111) - No such process 

你完成了。

编辑:傻系统管理员! 自动化你的生活,不工作! 如果我有一个我想监视的长dd过程,这里有一个单行程,将为您照顾整个辣酱玉米饼馅; 把这一切都放在一条线上:

  dd if=/path/to/bigimage of=/path/to/newimage conv=sparse bs=262144 & bgid=$!; while true; do sleep 1; kill -USR1 $bgid || break; sleep 4; done 

当然,你可以编写脚本,也许你的输入文件是$ 1,输出文件是$ 2。 这留给读者练习。 请注意,在杀死之前你需要那么小的睡眠,否则当它还没有准备好时,可能会试图向dd发送信号。 根据需要调整您的睡眠(甚至可以完全取消第二次睡眠)。

Bash- FTW! 🙂

在Ubuntu 16.04上

Ubuntu 16.04附带dd(coreutils)版本8.25 。 因此选项status=progress 支持的:-)

要使用它,只需添加status=progressdd命令。

示例:

 dd bs=4M if=/media/severus/tools-soft/OperatingSystems/ubuntu-16.04-desktop-amd64.iso of=/dev/null status=progress && sync 

给出状态为

 1282846183 bytes (1.2 GiB, 1.1 GiB) copied, 14.03 s, 101.9 MB/s 

在此处输入图像描述

最简单的是:

  dd if=... of=... bs=4M status=progress oflag=dsync 

oflag=dsync将使您的写入保持同步,因此status=progress信息更准确。 然而,它可能会慢一点。

我在dd上创建了bash包装器,它将使用pv来显示进度。 将它放入.bashrc并像往常一样使用dd

 # dd if=/dev/vvg0/root of=/dev/vvg1/root bs=4M 2GB 0:00:17 [ 120MB/s] [===========================================================>] 100% 0+16384 records in 0+16384 records out 2147483648 bytes (2.1 GB) copied, 18.3353 s, 117 MB/s 

资源:

 dd() { local dd=$(which dd); [ "$dd" ] || { echo "'dd' is not installed!" >&2 return 1 } local pv=$(which pv); [ "$pv" ] || { echo "'pv' is not installed!" >&2 "$dd" "$@" return $? } local arg arg2 infile local -a args for arg in "$@" do arg2=${arg#if=} if [ "$arg2" != "$arg" ] then infile=$arg2 else args[${#args[@]}]=$arg fi done "$pv" -tpreb "$infile" | "$dd" "${args[@]}" } 

我真的很喜欢ddrescue,它可以作为dd但是输出并且不会因错误而失败,相反它有一个非常先进的算法,尝试很难成功复制…还有很多GUI用于它

项目: https : //www.gnu.org/software/ddrescue

维基百科: https : //en.wikipedia.org/wiki/Ddrescue

在此处输入图像描述

所以今天我在dd运行时尝试在循环中运行kill感到有些沮丧,并且想出了这种方法来并行运行它们,很容易:

 function vdd { sudo dd "$@" & sudo sh -c "while pkill -10 ^dd$; do sleep 5; done" } 

现在只需在你通常使用dd任何地方使用vdd (它直接传递所有参数),你将获得每5秒打印一次的进度报告。

唯一的缺点是当dd完成时命令不会立即返回; 所以有可能这个命令可以让你在dd返回之前等待额外的5s,然后才会注意到并退出。

使用选项status=progress来获取转移期间的进度。

此外, conv=fsync将显示I / O错误。

例:

 sudo dd if=mydistrib.iso of=/dev/sdb status=progress conv=fsync 

如上所述,至少使用GNU coreutils或busybox中的’dd’,它将通过将进度信息打印到stderr来响应USR1信号。

我为dd编写了一个小包装器脚本,它显示了一个很好的百分比完成指示器,并试图不以任何方式干扰dd的进程或运行方式。 你可以在github上找到它:

http://github.com/delt01/dd_printpercent

不幸的是,这个SIGUSR1技巧只适用于GNU dd(来自coreutils包)或busybox的’dd’模式,在编译时启用了该特定function。 它不适用于大多数BSD系统中包含的’dd’,包括FreeBSD和OS X …… 🙁

这个强制dd每2秒提供一次stats,这是watch的默认值:

 watch killall -USR1 dd 

要从每2秒更改为每5秒,请添加-n 5选项,如下所示:

 watch -n 5 killall -USR1 dd 

您可以使用进度观察任何coreutils程序的progress - Coreutils Progress Viewer

它可以监控:

cp mv dd tar cat rsync grep fgrep egrep cut sort md5sum sha1sum sha224sum sha256sum sha384sum sha512sum adb gzip gunzip bzip2 bunzip2 xz unxz lzma unlzma 7z 7za zcat bzcat lzcat split gpg

您可以看到联机帮助页

您可以在命令运行时在单独的终端窗口中使用它,也可以使用dd命令启动它:

 dd if=/dev/sda of=file.img & progress -mp $! 

这里&分叉第一个命令并立即继续,而不是等到命令结束。

使用以下命令启动progress命令: -m因此它等待直到受监视的进程结束, -p所以它监视给定的pid和$! 是最后一个命令pid。

如果你用sudo发出dd,你也必须进步:

 sudo dd if=/dev/sda of=file.img & sudo progress -m # with no -p, this will wait for all coreutil commands to finish # but $! will give the sudo command's pid