您如何监视dd的进度?


654

dd是一个奇迹。它使您可以将一个硬盘驱动器复制到另一个硬盘驱动器,或将硬盘驱动器完全归零,依此类推。但是,一旦启动dd命令,就没有什么可告诉您它的进度了。它只是坐在光标所在的位置,直到命令最终完成。那么如何监控dd的进度呢?

Answers:


728

更新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:新status选项添加到dd(GNU Coreutils 8.24+)

dd在GNU Coreutils 8.24+(Ubuntu 16.04及更高版本)中,有一个新status选项可以显示进度:

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

输出量

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

76
pv bigfile.iso | dd of = / dev / yourdevice
离子溴。

18
请注意,“ dd”的参数在上半部分(管道的输入部分)中是合适的:dd if=/dev/zero bs=1M count=35000 | pv | dd of=VirtualDisk.raw
Sopalajo de Arrierez 2014年

6
pv bigfile.iso | dd of=VirtualDisk.raw bs=1M count=35000作品,经过验证。@SopalajodeArrierez,参数可以在第二个dd中给出。
SiddharthaRT 2014年

11
使用pv < /dev/sda > /dev/sdb似乎会获得更好的速度(来源
Nicola Feltrin

14
仅供参考。在装有Samsung 840 PRO SSD的计算机上进行的测试:dd if=/dev/urandom | pv | of=/dev/sdb写入速度为〜18MB / s,速度dd if=/dev/zero | pv | of=/dev/sdb为〜80MB / s,而普通的速度dd if=/dev/zero of=/dev/sdb为〜550MB / s(接近SSD的最大写入速度)。全部带有bs=4096000
泰德·汉森

461

HowTo:监视dd的进度

您可以使用以下kill命令监视dd的进度而无需暂停它。

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

sudo kill -USR1 $(pgrep ^dd)

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

如果您希望获得dd进度的定期更新,请输入:

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

watchdd每隔-n秒(-n5= 5秒)探测一次该过程,并在不停止的情况下进行报告。

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


19
这行得通,但有几点评论。首先,我不确定为什么您逃脱了反引号(如果是用于SO编辑器的话,您做错了)。其次,我建议您使用^ dd $,以防万一其他应用程序以dd为前缀运行。最后,您不需要sudo来发送USR1信号。否则,好的答案是+1。
gsingh2011

22
注意!这种方式可以在OSX下中断dd。
Maxim Kholyavkin 2014年

26
@Speakus您必须kill -INFO $(pgrep ^dd$)在BSD系统(如OSX)上使用。
Torben 2015年

20
sudo pkill -usr1 dd更容易记住,可以很好地工作(至少在Ubuntu 14.04上),而且键入的次数更少。
2015年

21
我之所以这样,是因为恐怕pv会像TeddHansen所示那样降低传输速度。另外,我敢打赌,很多人正在Google上搜索,因为他们已经开始dd操作了;)
sudo 2016年

104

一些方便的示例用法,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

而我最喜欢的克隆磁盘驱动器(用驱动器号替换X):

(pv -n /dev/sdX | dd of=/dev/sdX 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/

也用于存档自己。


3
您还需要dialog使用以下命令进行安装apt-get install dialog
k7k0 2015年

7
喜欢这个dialog例子。现在宁静
亚历克斯·格雷

您只能使用python调用该对话框吗?
mikeymop '16

1
感谢这个答案,发现dialog这将
极大

2
brew install pv dialog对于Mac。这位先生也以风格计算。太棒了
evilSnobu

62

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

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)

5
在Kubuntu Trusty上对我不起作用。按键绑定可能冲突?
jamadagni 2014年

14
很好 它可以在OSX下工作,但不能在ubuntu 14.04下工作
Maxim Kholyavkin 2014年

1
第一行由OS X生成,仅后三行来自dd
伊泰·格鲁杰夫

3
您应该能够在OS X等BSD上使用kill -INFO
macshome

3
这在Ubuntu上不起作用。Ctrl-T / Ctrl-Shift-T仅输出^T到终端(许多终端应用除外,它们会拦截Ctrl-Shift-T并打开一个新选项卡)。OSX / BSD上的许多搜索者都可能会喜欢这个答案,但应该明确指出,它不是针对Ubuntu(或一般而言是GNU / LInux?)的
mwfearnley

60

为了完整性:

版本8.24的的GNU的coreutils包括用于DD引入参数来打印进度的贴剂。

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

dd:new status =进度级别以定期打印统计信息

许多发行版(包括Ubuntu 16.04.2 LTS)都使用此版本。


只需添加我如何编译8.24 coreutils:apt install build-essentialapt-get build-dep coreutils,然后下载coreutils-8.25.tar.xz,tar xvf coreutils-8.25.tar.xz configure --prefix=$HOME/usr/local然后运行即可make。新编译的dd将在srcdir 下。您可以将其复制到/ bin并替换现有的以src / dd
格式

2
凉!我喜欢这个功能。教dd打印进度输出只花了大约30年的时间。:-)
Johannes Overmann

终于解脱了!我将立即在dd shell别名中添加此参数。
斯蒂芬·亨宁森

请注意,状态有时会以两个数字打印,一个以SI单位显示,而等效值以二进制单位显示(例如10 MB,9.5 MiB)。
palswim

33

最好是使用http://dcfldd.sourceforge.net/,通过apt-get轻松安装


3
感谢您指向dcfldd的指针,该指针与dd非常兼容,但具有一些不错的新功能。我特别喜欢标准进度。
弗洛伊德2013年

4
为什么dcfldd并不那么为人所知,这对我来说完全是个谜。
Freedom_Ben 2014年

28
可能是因为它的名字。
Giovanni Toraldo 2014年

默认情况下,它具有选项dd和选项status=on,用于进度消息,statusinterval=N(以N为块)用于消息更新频率和sizeprobe=[if|of]百分比指示符。我将其别名为DD:)
kavadias

25

本机进度状态已添加到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)

dd以root身份运行:

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

18

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

watch ls -l /pathtofile/filename

要仅查看文件大小(人类视角):

watch ls -sh /pathtofile/filename

也是一个可行的方法...
ζ--

3
很有用,尽管如果您将dd输出通过管道传输到文件以外的其他文件(例如,在将其写入磁盘之前先进行gzip压缩),则不一定有用。
Ponkadoodle 2014年

在特殊文件上不起作用。
约翰尼斯·奥弗曼

13

dd | pv | dd黑社会让我的50GB的虚拟机副本采取800秒,如只使用DD反对260秒。至少有了这个管道,pv根本不知道输入文件有多大,因此它无法告诉您您走了多远,因此按以下方式进行操作没有任何缺点-并且您获得了不错的速度优势:

我会避免在任何较大的物体上使用PV,并且(如果使用Bash):

Control-Z 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发送信号时死亡。根据需要调整睡眠(甚至可以完全取消第二个睡眠)。

重击-FTW!:-)


1
压缩while循环。使用watch
muru 2015年

1
@muru取决于。我不了解您的系统,但是在CentOS7 *上,输出有点乱码;它可读,但看起来不规则。同样,它会覆盖以前的输出,因此您会丢失dd速度的历史记录;我的在20 MB / s和300 MB / s之间变化。观察数字的变化和启发性也很有趣。我认为某些较大的差异是由于LVM精简池增加了我正在写入的LV的分配。*是的,这是一个ubuntu论坛,但我来这里是为了寻找“ dd监视器进度”。这是Google的第一个结果。
Mike S

哦,我的意思是在另一个终端或屏幕窗口中运行sudo watch pkill dd。然后dd舒适地观看统计数据。
muru

默认情况下,pkill不会发送SIGTERM吗?我什至不想尝试,因为pgrep dd在运行单个dd时会提供3个pid:kthreadd,oddjob和dd。我担心杀人会做什么。您可以使用pkill发送-USR1信号,但是同样,我不知道发送到内核线程或obbjob是否安全。watch命令看起来更简洁,但似乎为了避免while循环而采取了许多额外的步骤。通常,如果我在一个窗口中执行dd指令,则之后我将在同一shell中立即执行某些操作。while循环很安全:您确切地知道哪个pid可以接收信号。
Mike S

因为我使用,所以大多数情况下我都不在乎哪个PID会收到信号watch pkill -USR1 -x dd。由于我也将其watch用于其他类似的任务,因此这很自然。
muru



6

在Ubuntu 16.04上

Ubuntu 16.04带有dd(coreutils)版本8.25。因此,该选项status=progress Supported :-)

要使用它,只需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

在此处输入图片说明


5

使用选项status=progress获取传输过程中的进度。

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

例:

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


3

我已经创建了bash包装器ddpv用于显示进度。将其放入您的手机.bashrcdd照常使用:

# 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[@]}"
}

好的方法,但不适用于sudo或time之类的命令。
Maxim Kholyavkin

1
将其放在/ usr / local / bin / dd中,并放在顶部:#!/bin/bash。在底部:tmp=":${PATH}:"; tmp=${tmp/:/usr/local/bin:/:}; tmp=${tmp%:}; PATH=${tmp#:}; dd "$@"或者,您可能希望对dd位置进行硬编码。然后使用local dd=/usr/bin/dd。不要忘记添加可执行位:chmod +x /usr/local/dd
midenok

2

因此,今天我对尝试在运行kill时循环运行感到有些沮丧dd,并想出了一种轻松并行运行它们的方法:

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

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

唯一的缺点是,当dd完成时,该命令不会立即返回。因此,该命令有可能使您在dd返回之后等待另外5秒钟,直到它注意到并退出。


2

这会强制dd每2秒提供一次统计信息,这是手表的默认设置:

watch killall -USR1 dd

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

watch -n 5 killall -USR1 dd

2

以防万一来自CentOS的人碰巧找到了这个线程...

'status = progress'选项适用于CentOS 7.5和7.6

@davidDavidson的上述答案表示该功能是Coreutils 8.24中新添加的。

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

可能是这种情况,但是CentOS可能不会遵循相同的版本控制方案。

CentOS 7.6.1810随附的Coreutils版本为:

coreutils-8.22-23.el7.x86_64 : A set of basic GNU tools commonly used in shell scripts

并且所安装的dd的版本是:

[root@hostname /]# dd --version
dd (coreutils) 8.22
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Paul Rubin, David MacKenzie, and Stuart Kemp.

这显示了版本8.22

但是,我已经在CentOS 7.5和CentOS 7.6(都使用Coreutils的8.22版)上用dd测试了“ status = progress”,并且它可以正常工作。

我不知道为什么RedHat选择使用Coreutils的旧版本,但是功能确实存在于8.22中。


1

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

我为dd写了一个小包装脚本,该脚本显示了一个不错的百分比完成指标,并尝试不以任何方式干扰dd的过程或工作方式。您可以在github上找到它:

http://github.com/delt01/dd_printpercent

不幸的是,此SIGUSR1技巧仅适用于GNU dd(来自coreutils软件包)或busybox的“ dd”模式,并且在编译时启用了该特定功能。它不适用于大多数BSD系统(包括FreeBSD和OS X)中包含的股票“ dd” ... :(


链接已死。
ishmael

1

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

它可以监视:

cp mv dd tar tar 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
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.