Saya belum menggunakan dd
sebanyak itu, tapi sejauh ini saya belum gagal. Saat ini, saya sudah mendapatkan dd
selama lebih dari 12 jam - Saya menulis gambar kembali ke disk asalnya - dan saya sedikit khawatir, karena saya dapat dd
dari disk ke gambar dalam sekitar 7 jam.
Saya menjalankan OSX 10.6.6 pada MacBook dengan Core 2 Duo di 2.1ghz/core dengan RAM 4GB. Saya membaca dari .dmg pada hard drive 7200rpm (drive boot), dan saya menulis ke drive 7200rpm yang terhubung melalui konektor SATA-to-USB. Saya meninggalkan blocksize secara default, dan gambar sekitar 160gb.
EDIT: Dan, setelah 14 jam penuh stres, dd
bekerja dengan baik. Namun lain kali, saya akan menjalankannya melalui pv
dan melacaknya dengan strace
. Terima kasih untuk semua orang atas semua bantuan Anda.
Anda dapat mengirim dd
sinyal tertentu menggunakan perintah kill
untuk membuatnya mengeluarkan status saat ini. Sinyal adalah INFO
pada sistem BSD (termasuk OSX) dan USR1
di Linux. Dalam kasus Anda:
kill -INFO $PID
Anda dapat menemukan id proses ($PID
di atas) dengan perintah ps
; atau lihat pgrep dan pkill alternatif pada mac os x untuk metode yang lebih mudah.
Lebih sederhana, seperti AntoineG menunjukkan --- jawabannya , Anda dapat mengetik ctrl-T
di Shell yang menjalankan dd untuk mengirimkannya sinyal INFO
.
Sebagai contoh di Linux, Anda dapat membuat semua _ dd
aktif memproses status keluaran seperti ini:
pkill -USR1 -x dd
Setelah mengeluarkan statusnya, dd
akan terus mengatasi.
Di bawah OS X (tidak mencoba di Linux), Anda cukup mengetik Ctrl+T dalam terminal yang menjalankan dd
. Ini akan mencetak output yang sama dengan kill -INFO $PID
, ditambah penggunaan CPU:
load: 1.40 cmd: dd 34536 uninterruptible 3.49u 64.58s
5020305+0 records in
5020304+0 records out
2570395648 bytes transferred in 4284.349974 secs (599950 bytes/sec)
Saya mengetahui tentang hal itu membaca utas ini, dan mencoba membuka tab baru di terminal saya tetapi mencampur ⌘+T dengan Ctrl+T.
Untuk dd
, Anda dapat mengirim sinyal . Untuk perintah lain yang sedang membaca atau menulis ke file, Anda dapat melihat posisinya dalam file dengan lsof
.
lsof -o -p1234 # where 1234 is the process ID of the command
lsof -o /path/to/file
Jika Anda berencana terlebih dahulu, pipa data melalui pv
.
Saya biasanya melampirkan strace
ke proses yang berjalan (dengan -p $PID
opsi) untuk melihat apakah tetap diblokir dalam panggilan sistem atau jika masih aktif.
Atau, jika Anda merasa gugup mengirim sinyal ke dd berjalan, mulai dd lain untuk memvalidasi jika ini berfungsi.
Untuk waktu berikutnya, Anda bisa menggunakan pv
dari awal (jika tersedia melalui manajer paket Anda, instal). Ini adalah utilitas dengan tujuan tunggal menyalurkan input ke output dan memantau kemajuan dan kecepatan.
Kemudian, untuk menulis gambar ke drive, katakan dengan ukuran blok 4MB:
pv -ptearb /path/to/image.bin | dd iflag=fullblock of=/dev/whatever bs=4M
Selain dari buffering awal (diimbangi dengan sinkronisasi akhir, yang dapat dilakukan melalui dd
jika Anda mau), ini akan menampilkan bilah kemajuan, kecepatan rata-rata, kecepatan saat ini, dan ETA.
iflag=fullblock
opsi memaksa dd untuk mengambil blok input penuh melalui pv
, jika tidak, Anda berada pada belas kasihan pipa untuk ukuran blok.
Untuk ke arah lain gunakan dd untuk membaca dan pv untuk menulis, meskipun Anda harus secara eksplisit menentukan ukuran jika sumbernya adalah perangkat blok. Untuk perangkat 4GB:
dd if=/dev/whatever bs=4M | pv -ptearb -s 4096m > /path/to/image.bin
Anda juga dapat menentukan ukuran secara otomatis, seperti:
dd if=/dev/whatever bs=4M | pv -ptearb -s `blockdev --getsize64 /dev/whatever` > /path/to/image.bin
Tidak masalah urutan apa yang Anda lakukan dd
dan pv
in, itu sepenuhnya terkait dengan kinerja - jika perangkat yang Anda baca memiliki kinerja optimal untuk pemblokiran tertentu yang ingin Anda lakukan. gunakan dd
alih-alih pv
untuk mengakses perangkat itu. Anda bahkan dapat menempelkan dd
di kedua ujungnya jika Anda mau, atau tidak sama sekali jika Anda tidak peduli:
pv -ptearb /path/to/image.bin > /dev/whatever
sync
Pada coreutils
v8.24, dd
memiliki dukungan asli untuk menunjukkan kemajuan. Cukup tambahkan opsi status=progress
.
Contoh:
dd if=Arch.iso of=/dev/sdb bs=4M status=progress
ddrescue
akan memberi Anda statistik saat sedang berjalan.
Saya mulai menggunakan dcfldd (1), yang menunjukkan operasi dd dengan cara yang lebih baik.
Kadang-kadang Anda mungkin tidak dapat menggunakan sinyal INFO atau USR1 karena aliran stderr proses dd
tidak dapat diakses (mis. Karena terminal tempat eksekusi itu sudah ditutup). Dalam hal ini, solusinya adalah dengan melakukan hal berikut (diuji pada FreeBSD, mungkin sedikit berbeda di Linux):
Gunakan iostat
untuk memperkirakan laju tulis rata-rata (MB/d) ke perangkat target, mis .: .:
iostat -d -w30 ada0
Ganti nama perangkat target Anda dengan ada0
di sini, dan tunggu sebentar untuk memberikan hasil beberapa. Parameter "w" menentukan berapa detik antara sampel. Menambahnya akan memberikan perkiraan rata-rata yang lebih baik dengan varian yang lebih sedikit, tetapi Anda harus menunggu lebih lama.
Gunakan ps
untuk menentukan berapa lama dd
telah berjalan:
ps -xo etime,command | grep dd
Ubah ini menjadi detik untuk mendapatkan runtime total detik.
Dapatkan ukuran perangkat dalam MB dengan:
grep ada0 /var/run/dmesg.boot
Ganti nama perangkat target Anda dengan ada0
. Bagi hasil dengan rata-rata tingkat penulisan untuk mendapatkan total waktu transfer dalam detik. Kurangi waktu yang sudah berjalan sejauh ini untuk mendapatkan sisa waktu.
Strategi ini hanya berfungsi jika dd
telah menulis terus menerus pada tingkat penulisan rata-rata saat ini sejak dimulai. Jika proses lain bersaing untuk sumber daya CPU atau I/O (termasuk bus I/O) maka dapat mengurangi tingkat transfer.
Anda dapat menggunakan progress
yang, secara khusus, menunjukkan progres running dd
. Itu menggunakan /proc/$pid/fd
dan /proc/$pid/fdinfo
yang juga bisa Anda monitor dengan tangan.
Ketika dd
dieksekusi, saya menjalankan ini di terminal lain sebagai root:
while pgrep ^dd; do pkill -INFO dd; sleep 1; done
Ia mencetak status dd
setiap 1 detik di jendela terminal asli di mana dd
mengeksekusi, dan berhenti ketika perintah selesai.
Baris wchar
(karakter tertulis) di /proc/$pid/io
Dapat memberi Anda informasi yang tepat tentang proses dd
. Selama itu berubah, dd
Anda masih berfungsi!
Berikut ini adalah skrip php kecil yang rapi, yang dapat Anda simpan dan kemudian jalankan dengan php filename.php
Selama dd
untuk menampilkan byte yang ditulis. Manfaat Nice menonton /proc/$pid/io
Lebih dari kill -USR1 $(pidof dd)
adalah Anda tidak harus beralih antar terminal, yang tidak selalu menjadi pilihan.
<?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";
}