Bagaimana saya tahu jika dd masih berfungsi?


147

Saya belum terlalu ddbanyak menggunakan, tapi sejauh ini belum gagal saya. Saat ini, saya sudah ddberjalan selama lebih dari 12 jam - saya menulis gambar kembali ke disk asalnya - dan saya sedikit khawatir, karena saya dapat dddari disk ke gambar 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 stres murni, ternyata ddberhasil dengan baik. Namun lain kali, saya akan menjalankannya pvdan melacaknya strace. Terima kasih untuk semua orang atas semua bantuan Anda.


7
Tidak menjawab pertanyaan Anda, tetapi waktu Anda IMO cukup tinggi. Apakah Anda ingat untuk meneruskan ukuran blok yang lebih besar ke dd selain dari 512 byte default? dd ... bs=16Madalah saran saya, mengingat RAM Anda, ukuran dan kecepatan disk.
Juliano

Saya tidak melakukannya, hanya karena saya ingin bermain aman. Saya akan mencobanya lain kali. Terima kasih.
eckza

Dalam pengalaman saya, ddpada Mac OS X memiliki kecenderungan untuk membeku ke titik di mana saya bahkan tidak dapat mematikan proses, tetapi harus me-restart sistem. Saya resor untuk melakukan pekerjaan pada VM Linux.
ssc

Jawaban:


173

Anda dapat mengirim ddsinyal tertentu menggunakan killperintah untuk membuatnya mengeluarkan statusnya saat ini. Sinyal ada INFOdi sistem BSD (termasuk OSX) dan USR1di Linux. Dalam kasus Anda:

kill -INFO $PID

Anda dapat menemukan id proses (di $PIDatas) dengan psperintah; atau lihat pgrep dan pkill alternatif di mac os x untuk metode yang lebih mudah.

Lebih sederhana, seperti yang ditunjukkan AntoineG dalam jawabannya , Anda dapat mengetikkan ctrl-Tshell yang menjalankan dd untuk mengirimkan INFOsinyal.

Sebagai contoh di Linux, Anda dapat membuat semua ddstatus keluaran proses aktif seperti ini:

pkill -USR1 -x dd

Setelah mengeluarkan statusnya, ddakan terus mengatasi.


9
Oh, sangat keren. Anda dapat menggabungkannya denganpkill -USR1 -x dd
Michael Mrozek

9
@kivetros: Pada sistem BSD, Anda perlu mengirim INFOsinyal. Linux tidak memiliki SIGINFO dan menggunakan USR1sebagai gantinya.
Gilles

5
Sinyal SIGUSRx adalah untuk program melakukan apa yang mereka inginkan, sebagai lawan dari memiliki makna standar. SIGWINCH, misalnya, dinaikkan ketika terminal telah mengubah ukurannya dan program mungkin perlu menggambar ulang layarnya. Sistem operasi tidak mengirimkan SIGUSRx sehingga tersedia untuk penggunaan khusus.
LawrenceC

11
Mengirimkan dd sinyal USR1 terlalu cepat setelah dimulai (yaitu dalam skrip bash, baris setelah Anda memulainya) sebenarnya akan menghentikannya. Letakkan 0,1 detik di antaranya dan itu akan menampilkan kemajuan dengan benar. Omong-omong, perintah dd yang sangat bagus untuk menguji USR1 / INFO aktif dd if=/dev/zero of=/dev/null. :)
Lauritz V. Thaulow

11
BTW, semua BSD "benar" mengirim SIGINFO ke grup proses latar depan jika karakter status (Ctrl + T secara default) dikirim ke terminal. Tapi saya tidak tahu apakah itu benar untuk MacOSX.
Netch

100

Di bawah OS X (tidak mencoba di Linux), Anda cukup mengetik Ctrl+ Tdi terminal yang berjalan 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 + Tdengan Ctrl+ T.


1
Oh, oke, jadi loadapakah penggunaan CPU?
pje

ini adalah solusi yang jauh lebih baik!
Stephn_R

Saya mencoba di dd di Linux, itu hanya bergema ^Tke terminal.
mwfearnley

1
pastikan Anda melakukan ctrl + shift + T di terminal mac
JBaczuk

26

Sebab dd, Anda bisa mengirim sinyal . Untuk perintah lain yang sedang membaca atau menulis ke file, Anda dapat melihat posisinya di file 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.


1
pv terlihat luar biasa - saya pasti akan menggunakannya lain kali. Terima kasih banyak.
eckza

1
+1 - pvsepertinya hanya tiket.
boehj

17

Cara yang lebih umum adalah menggunakan iotopyang menampilkan jumlah disk saat ini membaca / menulis per program.

EDIT: iotop -ohanya tampilkan program yang melakukan operasi I / O saat ini (terima kasih Jason C untuk komentar ini).


1
Ini juga metode pemeriksaan cepat pilihan saya. iotop -oakan menyembunyikan proses yang tidak melakukan IO dan membuatnya lebih mudah untuk mengetahui apa yang sedang terjadi.
Jason C

13

Saya biasanya melampirkan straceproses yang berjalan (dengan -p $PIDopsi) 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.


2
Bagaimana tepatnya Anda akan melampirkan strace? Juga, saya memang memulai yang lain dddan mengirim salah satu sinyal yang disarankan untuk itu, dan ... itu membunuhnya.
eckza

2
Jika Anda tahu pid dari proses menjalankan dd, lakukan saja strace -p <pid>. Anda akan melihat log semua panggilan sistem yang dipanggil oleh proses (kebanyakan membaca dan menulis)
philfr

11

Untuk waktu berikutnya, Anda bisa menggunakannya pvdari 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 penyangga awal (diimbangi dengan sinkronisasi akhir, yang dapat dilakukan melalui ddjika Anda mau), ini akan menampilkan bilah kemajuan, kecepatan rata-rata, kecepatan saat ini, dan ETA.

The iflag=fullblockpasukan pilihan dd untuk mengambil blok penuh masukan melalui pv, jika Anda pada belas kasihan dari 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 apa pun urutan dddan urutannya pv, ini sepenuhnya terkait dengan kinerja - jika perangkat yang Anda baca memiliki atau dari memiliki kinerja optimal untuk ukuran blok tertentu yang ingin Anda gunakan ddalih-alih pvmengakses perangkat itu. Anda bahkan dapat menempelkannya dddi kedua ujungnya jika Anda mau, atau tidak sama sekali jika Anda tidak peduli:

pv -ptearb /path/to/image.bin > /dev/whatever
sync

10

Pada coreutilsv8.24, ddmemiliki dukungan asli untuk menunjukkan kemajuan. Cukup tambahkan opsi status=progress.

Contoh:

dd if=arch.iso of=/dev/sdb bs=4M status=progress

Sumber



4

Kadang-kadang Anda mungkin tidak dapat menggunakan sinyal INFO atau USR1 karena aliran ddproses stderr tidak dapat diakses (misalnya karena terminal di mana ia dieksekusi sudah ditutup). Dalam hal ini, solusinya adalah dengan melakukan hal berikut (diuji pada FreeBSD, mungkin sedikit berbeda di Linux):

  1. Gunakan iostatuntuk memperkirakan tingkat penulisan rata-rata (MB / s) ke perangkat target, misalnya:

    iostat -d -w30 ada0

    Gantilah nama perangkat target Anda di ada0sini, dan tunggu sebentar hingga hasilnya beberapa. Parameter "w" menentukan berapa detik antar sampel. Menambahnya akan memberikan perkiraan rata-rata yang lebih baik dengan varians yang lebih sedikit, tetapi Anda harus menunggu lebih lama.

  2. Gunakan psuntuk menentukan berapa lama ddtelah berjalan:

    ps -xo etime,command | grep dd

    Konversikan ke detik untuk mendapatkan runtime total detik.

  3. Kalikan total detik runtime dengan rata-rata tingkat penulisan untuk mendapatkan MB total yang ditransfer.
  4. 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 ddtelah menulis terus menerus pada tingkat menulis rata-rata saat ini sejak dimulai. Jika proses lain bersaing untuk sumber daya CPU atau I / O (termasuk bus I / O) maka dapat mengurangi kecepatan transfer.


4

Saya mulai menggunakan dcfldd (1), yang menunjukkan operasi dd dengan cara yang lebih baik.


2

Ketika ddsedang mengeksekusi, saya menjalankan ini di terminal lain sebagai root:

while pgrep ^dd; do pkill -INFO dd; sleep 1; done

Ini mencetak ddstatus setiap 1 detik di jendela terminal asli tempat ddeksekusi, dan berhenti ketika perintah dilakukan.


Keren abis. Bekerja dengan baik di sini di bawah El Capitan
Stefano Mtangoo

2

Anda dapat menggunakan progressyang, khususnya, menunjukkan progres lari dd. Ini menggunakan /proc/$pid/fddan /proc/$pid/fdinfo yang Anda juga dapat memonitor dengan tangan.


1

The wcharline (karakter yang ditulis) dalam /proc/$pid/iodapat memberikan informasi yang tepat tentang ddproses. Selama itu berubah, Anda ddmasih bekerja!

Berikut ini adalah skrip php kecil yang rapi, yang dapat Anda simpan dan kemudian jalankan dengan php filename.phpselama dduntuk menampilkan byte yang ditulis. Manfaat bagus menonton /proc/$pid/iolebih kill -USR1 $(pidof dd)adalah bahwa Anda tidak perlu beralih di antara terminal, yang tidak selalu 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";
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.