dd
,但是到目前为止,这还没有使我失望。现在,我已经将dd
进行了12个小时以上的工作-我正在将映像写回到它来自的磁盘中-我有点担心,因为我能够从磁盘将dd
映像在大约7个小时内。 我在配备Core 2 Duo的MacBook上运行OSX 10.6.6,速度为2.1ghz / core,带有4GB RAM。我正在从7200rpm硬盘驱动器(引导驱动器)上的.dmg中读取,并且正在写入通过SATA-USB连接器连接的7200rpm驱动器。我在默认情况下保留了块大小,图像约为160gb。不过,下一次,我将通过
dd
运行它,并使用pv
对其进行跟踪。感谢大家的帮助。#1 楼
您可以使用dd
命令向kill
发送特定信号,以使其输出当前状态。该信号在BSD系统(包括OSX)上是INFO
,在Linux上是USR1
。在您的情况下:kill -INFO $PID
您可以使用
$PID
命令找到进程ID(上面的ps
);或在Mac os x上查看pgrep和pkill替代方法,以获得更方便的方法。 以Linux为例,可以使所有活动的
ctrl-T
进程的输出状态如下:pkill -USR1 -x dd
输出状态后,
INFO
将继续应对。评论
哦,太酷了。您可以将它们与pkill -USR1 -x dd结合使用
– Michael Mrozek
2011年4月13日在17:26
@kivetros:在BSD系统上,您需要发送INFO信号。 Linux没有SIGINFO,而是使用USR1。
–吉尔斯'所以-不再是邪恶的'
2011年4月13日在18:50
SIGUSRx信号用于程序执行其所需的操作,而不是具有标准化含义。例如,当终端更改其大小并且程序可能需要重绘其屏幕时,会引发SIGWINCH。操作系统不会发送SIGUSRx,因此可以用于自定义用途。
– LawrenceC
2011年4月14日在1:17
实际上,在启动USR1信号后过早发送dd(即在bash脚本中,即启动它后的行)发送dd实际上会终止它。在两者之间放置0.1秒的睡眠,它将正确输出其进度。顺便说一句,用于测试USR1 / INFO的一个非常好的dd命令是dd if = / dev / zero of = / dev / null。 :)
–Lauritz V. Thaulow
2011年4月14日在8:51
顺便说一句,如果状态字符(默认为Ctrl + T)发送到终端,则所有“真” BSD都会将SIGINFO发送到前台进程组。但是我不知道MacOSX是否适用。
– Netch
2012年11月1日在20:14
#2 楼
在OS X(不在Linux上尝试)下,您只需在运行dd
的终端中键入Ctrl + T即可。它将输出与kill -INFO $PID
相同的输出,外加CPU使用率:但是将⌘+ T与Ctrl + T混合使用。评论
哦,好了,那么CPU使用率是负担吗?
– pje
2014年9月6日20:21在
这真是一个更好的解决方案!
– Stephn_R
15年3月18日在5:41
我在Linux上的dd中尝试过,它只是将^ T回显到终端。
–mwfearnley
17年1月6日在14:48
确保在Mac终端中执行ctrl + shift + T
– JBaczuk
17年8月30日在15:31
#3 楼
对于dd
,您可以发送信号。对于正在读取或写入文件的其他命令,可以使用lsof
观察它们在文件中的位置。 pv
。评论
PV看起来很棒-下次我一定会用它。非常感谢。
–eckza
2011年4月14日在1:27
+1-PV看起来就像门票。
– boehj
2011年7月13日在7:00
#4 楼
一种更通用的方法是使用iotop
来显示每个程序的当前磁盘读取/写入量。对此评论)。 评论
这也是我首选的快速检查方法。 iotop -o将隐藏未执行IO的进程,并使其一目了然。
–杰森C
2014年6月4日19:51
#5 楼
我通常将strace
附加到这样一个正在运行的进程(带有-p $PID
选项),以查看它是否在系统调用中保持阻塞或是否仍处于活动状态。 或者,如果您对向运行中的dd发送信号感到不安,请启动另一个dd以验证其是否有效。
评论
您将如何精确地附加strace?另外,我确实启动了另一个dd并向其中发送了建议的信号之一,并且...杀死了它。
–eckza
2011年4月14日在13:15
如果您知道正在运行的dd进程的pid,只需执行strace -p
– philfr
2011年4月14日14:07
#6 楼
对于下一次,您可以从一开始就使用pv
(如果可以通过软件包管理器使用它,请安装它)。这是一个实用程序,其唯一目的是通过管道传输输入来输出并监视进度和速度。然后将映像写入驱动器,例如以4MB块大小:
pv -ptearb /path/to/image.bin | dd iflag=fullblock of=/dev/whatever bs=4M
除了初始缓冲(如果需要,可以通过
dd
进行最终同步补偿),这将显示进度条,平均速度,当前速度和ETA。 br /> iflag=fullblock
选项强制dd通过pv
捕获完整的输入块,否则您将无法决定块大小。要使用另一种方法,请使用dd读取和pv写入,但是如果源是块设备,则必须显式指定大小。对于4GB设备:
dd if=/dev/whatever bs=4M | pv -ptearb -s 4096m > /path/to/image.bin
还可以自动确定大小,例如:
dd if=/dev/whatever bs=4M | pv -ptearb -s `blockdev --getsize64 /dev/whatever` > /path/to/image.bin
依次执行
dd
和pv
的顺序实际上并不重要,这完全与性能相关-如果要读取或读取的设备对于某些块大小具有最佳性能,则您想使用dd
而不是pv
来访问该设备。如果需要,您甚至可以在两端都贴上dd
,或者根本不在意的话根本不用:#7 楼
从coreutils
v8.24开始,dd
具有显示进度的本机支持。只需添加选项status=progress
即可。示例:
dd if=arch.iso of=/dev/sdb bs=4M status=progress
源
评论
linux的最佳答案。我尝试使用ubuntu并成功。在Mac中Ctrl + T
–byOnti
20/09/10在19:18
#8 楼
ddrescue
会在运行时为您提供统计信息。演示:
http://www.youtube.com/watch?v=vqq9A01geeA#t=144s
评论
这可能对下次有用,但不会帮助OP了解当前命令是否冻结。
–user22304
2012年11月2日13:11
#9 楼
有时您可能无法使用INFO或USR1信号,因为无法访问dd
进程的stderr流(例如,因为执行它的终端已经关闭)。在这种情况下,一种解决方法是执行以下操作(在FreeBSD上进行测试,在Linux上可能会略有不同):使用
iostat
估算平均写入率(MB / s)到目标设备,例如:iostat -d -w30 ada0
在此处用目标设备名称替换
ada0
,然后等待一分钟,以得出一些结果。 “ w”参数确定样本之间的间隔秒数。增大它可以得到更好的平均估计,并且方差较小,但是您必须等待更长的时间。使用
ps
确定dd
的运行时间:ps -xo etime,command | grep dd
将其转换为秒以获取运行时的总秒数。
将运行时的总秒数乘以平均写入率即可获得传输的总MB。
通过以下方法获取设备大小(以MB为单位):
grep ada0 /var/run/dmesg.boot
用目标设备名称替换
ada0
。将结果除以平均写入率即可得到总传输时间(以秒为单位)。减去到目前为止已运行的时间以节省时间。仅当
dd
自开始以来一直以当前的平均写入速率连续写入时,此策略才有效。如果其他进程正在争用CPU或I / O资源(包括I / O总线),则可能会降低传输速率。#10 楼
我开始使用dcfldd(1),它以更好的方式显示了dd操作。#11 楼
您可以使用progress
,它特别显示正在运行的dd
的进度。它使用/proc/$pid/fd
和/proc/$pid/fdinfo
,您也可以手动对其进行监视。#12 楼
在执行dd
时,我以root用户身份在另一个终端中运行此命令:命令完成后退出。评论
非常酷。在El Capitan领导下工作得很好
– Stefano Mtangoo
17 Mar 9 '17 at 13:51
#13 楼
wchar
中的/proc/$pid/io
行(手写字符)可以为您提供有关dd
进程的准确信息。只要它更改,您的dd
仍然可以正常工作!与php filename.php
相比,观看dd
的好处是不必在端子之间进行切换,这并不总是一种选择。<?php
/** Time between refreshs in seconds */
$refresh = 1;
/**
* Start of Script
*/
if (!($pid = exec('pidof dd')))
exit("no dd running\n");
$history = array();
$break_ms = $refresh * 1000000;
$start_time = exec("ls -ld /proc/$pid --time-style=+\"%s\" | egrep -o [0-9]{10}");
fprintf(STDOUT, "PID: %s\n", $pid);
fprintf(STDOUT, "START TIME: %s\n\n", date("Y-m-d H:i:s", $start_time));
while (true) {
if (isset($curr))
array_push($history, $curr);
if (count($history) > 10) array_shift($history);
$oldest = reset($history);
$latest = end($history);
/**
* get number of written bytes from /proc/$pid/io
*/
#if (!($curr = exec("cat /proc/$pid/io | grep ^write_bytes | sed 's/write_bytes: //g'")))
# break;
/* prepare proc_open() parameter */
$descriptorspec = array(
0 => array('pipe', 'r'), // stdin
1 => array('pipe', 'w'), // stdout
2 => array('pipe', 'w'), // stderr
);
$process = proc_open("cat /proc/$pid/io | grep ^write_bytes | sed 's/write_bytes: //g'", $descriptorspec, $pipes);
if (!is_resource($process)) break;
$stdout = stream_get_contents($pipes[1]);
$stderr = stream_get_contents($pipes[2]);
proc_close($process);
if (!empty($stderr)) break;
$curr = trim($stdout);
/**
* caculate elapsed time from start */
$time_elapsed = time() - $start_time;
/**
* avg speed since start */
$avg = $time_elapsed > 0 ? round($curr / $time_elapsed) : 0;
/**
* avg speed of last 10 updates */
if (count($history) > 0)
$speed = human_file_size(round(($latest - $oldest) / count($history) / $refresh));
$output = sprintf("\rBYTES WRITTEN: %s [%s] :: CURRENT: %s/s :: AVERAGE: %s/s :: ELAPSED: %s", $curr, human_file_size($curr), isset($speed) ? $speed : 0, human_file_size($avg), gmdate("H:i:s", $time_elapsed));
printf("%s%s", $output, str_repeat(" ", exec("tput cols") - strlen($output)));
usleep($break_ms);
}
fprintf(STDOUT, "\ndd has finished!\n\n");
function human_file_size($size,$unit="") {
if( (!$unit && $size >= 1<<30) || $unit == "GB")
return number_format($size/(1<<30),2)." GB";
if( (!$unit && $size >= 1<<20) || $unit == "MB")
return number_format($size/(1<<20),2)." MB";
if( (!$unit && $size >= 1<<10) || $unit == "kB")
return number_format($size/(1<<10),2)." kB";
return number_format($size)." bytes";
}
#14 楼
如果写入慢速驱动器(例如USB驱动器),则可能不仅要了解命令dd
本身的进度,还要了解实际写入目标设备的进度。<知道进程何时完成的一种方法是在dd命令后运行
sync
并等待它完成刷新缓冲区的过程,以便终端窗口返回提示。但是仍然没有进展。您可以通过例如使用mkusb的shellscript watch-flush
观察“脏”数据来监视刷新的进度。此shell脚本使用系统文件/proc/meminfo
中的数据。更简单地修改dd
命令行以使其定期刷新缓冲区,例如在写入每个兆字节后,同时显示进度,例如sudo dd if=file.img bs=1M of=/dev/sdx status=progress oflag=dsync
请检查并仔细检查,以指定正确的目标设备。否则,您可能会覆盖有价值的数据。
dd
完全按照您的指示进行操作,因此,它已赢得了“数据销毁者”的绰号。克隆任务。它会在dd
周围缠上一条安全带:可以帮助您识别目标设备,并在启动该过程之前对其进行仔细检查。
评论
没有回答您的问题,但是IMO的时间很高。您是否还记得将默认的512字节以外的更大的块大小传递给dd?考虑到您的RAM,磁盘大小和速度,dd ... bs = 16M是我的建议。我没有,只是因为我想安全玩。不过,下次我会尝试的。谢谢。
根据我的经验,Mac OS X上的dd趋于冻结,以至于我什至无法终止进程,而不得不重新启动系统。然后,我求助于在Linux VM上进行工作。