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

#1 楼

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(GNU Coreutils 8.24+)中添加了新的dd选项。一个新的dd选项来显示进度:

示例

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


输出

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


评论


pv bigfile.iso | dd of = / dev / yourdevice

–离子Br。
2013年12月17日在21:02

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

– Sopalajo de Arrierez
2014年3月28日在0:05



pv bigfile.iso | dd of = VirtualDisk.raw bs = 1M count = 35000有效,已验证。 @SopalajodeArrierez,参数可以在第二个dd中给出。

–SiddharthaRT
14-10-20在12:17

使用pv / dev / sdb似乎速度更快(源)

–尼古拉·费特林(Nicola Feltrin)
2015年2月20日在13:30



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

–泰德·汉森(Tedd Hansen)
16年5月7日在21:18

#2 楼

在HowTo中:监视dd

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

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

sudo kill -USR1 $(pgrep ^dd)


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

如果您想定期更新dd的进度,请输入:每隔-n秒(watch = 5秒)探测一次dd进程,并在不停止的情况下进行报告。

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

评论


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

–gsingh2011
13年7月14日在20:25

注意!这种方式可以在OSX下中断dd。

– Maxim Kholyavkin
2014年11月17日下午6:33

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

–托本
2015年6月6日在8:22

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

– Phizes
2015年9月7日于12:59

我之所以这样,是因为恐怕光伏会像TeddHansen所示那样拖慢传输速度。另外,我敢打赌,很多人正在谷歌搜索,因为他们已经开始了dd操作;)

– sudo
16年7月7日在18:22



#3 楼

使用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


注意:第一个示例比dd if=/dev/urandom | pv | dd of=/dev/null少输入5个字符。

和我最喜欢的用于克隆磁盘驱动器(用驱动器号替换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 /

也用于存档自己。

评论


您还需要使用命令apt-get install dialog安装对话框。

–k7k0
15年4月29日在19:06

喜欢对话框的例子。现在宁静!

–alex灰色
15年11月22日在20:47

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

– mikeymop
16年4月29日在19:50

感谢这个答案,发现对话框这将在编写shell脚本方面提供疯狂帮助:D

–霍姆斯
16年8月19日在22:35

适用于Mac的brew install pv对话框。这位先生也以风格来计算。太棒了

–evilSnobu
18年4月5日在13:18

#4 楼

在运行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)


评论


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

–贾马达格尼
2014年11月15日下午4:33

很好它在OSX下工作,但在ubuntu 14.04下不工作

– Maxim Kholyavkin
2014年11月17日下午6:39

第一行由OS X生成,只有后三行来自dd。

– Itay Grudev
2015年4月1日在4:49

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

–macshome
2015年9月19日下午13:07

这在Ubuntu上不起作用。 Ctrl-T / Ctrl-Shift-T只会将^ T输出到终端(许多终端应用程序会拦截Ctrl-Shift-T并打开一个新选项卡)。 OSX / BSD上的许多搜索者可能会喜欢这个答案,但是应该明确指出,它不适用于Ubuntu(或一般来说是GNU / LInux?)

–mwfearnley
17年11月11日在16:28

#5 楼

为了完整起见:

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

引入此更改的提交具有注释:


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


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

评论


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

–霍姆斯
16年8月19日在22:37

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

–约翰尼斯·奥弗曼(Johannes Overmann)
17年4月17日在9:34

终于解脱了!我将立即在dd shell别名中添加此参数。

–斯蒂芬·亨宁森(Stephan Henningsen)
17年5月31日在20:14



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

–palswim
17年9月29日在19:29

#6 楼

最好的方法是使用http://dcfldd.sourceforge.net/,通过apt-get
易于安装

评论


感谢dcfldd的指针,它与dd非常兼容,但还具有一些不错的新功能。我特别喜欢标准进度。

–弗洛伊德
2013年12月20日上午9:46

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

– Freedom_Ben
2014年3月3日14:00

可能是因为它的名字。

–乔瓦尼·托拉尔多(Giovanni Toraldo)
2014年12月28日在9:31

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

–卡瓦迪亚斯
18年5月8日在17:09

#7 楼

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


#8 楼

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


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

watch ls -sh /pathtofile/filename


评论


也是可行的方法...

– Nanofarad
2012年12月7日在21:59

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

– Ponkadoodle
2014年7月3日,3:32

在特殊文件上不起作用。

–约翰尼斯·奥弗曼(Johannes Overmann)
18年2月3日在22:10

#9 楼

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


您已完成。

编辑:Silly Systems Administrator!自动化生活,不工作!如果我要监视很长的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! :-)

评论


压缩while循环。使用手表。

–muru
2015年5月7日15:00

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

– Mike S
15年5月7日在17:51



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

–muru
2015年5月7日在18:02

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

– Mike S
15年5月8日在14:01

大多数情况下,我不在乎哪个pid会收到信号,因为我使用watch pkill -USR1 -x dd。由于我还将监视用于其他类似任务,因此这一任务自然而然。

–muru
2015年5月8日14:07

#10 楼

http://linuxcommando.blogspot.com/2008/06/show-progress-during-dd-copy.html

基本:

kill -USR1 < dd pid >


评论


“ pkill -USR1 dd”是我所知道的最简单的版本(只要您只运行dd的一个实例,无论如何)。在我的系统上,我需要sudo:“ sudo pkill -USR1 dd”。键入dd命令后可以使用,并且不需要安装任何新功能。

–弗雷德·汉密尔顿
15年5月18日在18:49



#11 楼

在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

将状态设置为


#12 楼

最简单的方法是:

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


oflag=dsync将使您的写作保持同步,因此status=progress的信息更加准确。但是可能会慢一些。

评论


根据gnu.org/software/coreutils/manual/html_node/dd-invocation.html,使用conv = fsync更好

–陈登大
17年6月24日在12:49



谢谢你!我正在对远程lvm2进行dd,而bs = 4M使我的传输增加了20倍,并且进度指示非常好。

–Lonnie Best
18年1月19日在8:26

#13 楼

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

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

示例:

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


#14 楼

我真的很喜欢ddrescue,它可以像dd一样工作,但是可以提供输出,并且不会出错,相反,它具有非常先进的算法,并且会非常努力地进行成功的复制...还有很多GUI

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

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



#15 楼

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

watch killall -USR1 dd


要从每2秒更改为每5秒,请添加-n 5选项,例如this:

watch -n 5 killall -USR1 dd


#16 楼

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


评论


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

– Maxim Kholyavkin
2014年11月17日在7:28

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

– Midenok
2014年11月19日在7:06



#17 楼

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

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


现在只需在通常使用vdd的任何地方使用dd(它将所有参数直接传递通过),就会每5秒打印一次进度报告。 dd完成后立即返回;因此,该命令有可能使您在dd返回之后等待另外5秒钟,直到它注意到并退出。

#18 楼

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

'status = progress'选项与CentOS 7.5和7.6一起使用

@davidDavidson的上述回答意味着该功能是Coreutils 8.24中新添加的。


GNU coreutils的版本8.24包括一个dd补丁,引入了一个用于打印进度的参数。 br />可能是这种情况,但是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中。

#19 楼

如上所述,至少使用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
19年9月4日在21:46

#20 楼

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

它可以监视:

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 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