web-dev-qa-db-ja.com

ddがまだ機能しているかどうかはどうすればわかりますか?

ddはあまり使用していませんが、今のところまだ失敗していません。現在、ddを12時間以上行っています-元のディスクにイメージを書き込んでいます-ddをディスクからイメージに約7時間で送信します。

OSX 10.6.6を実行していて、コア2 Duoと2.1ギガバイト/コア、4ギガバイトのRAMを搭載したMacBookを使用しています。 7200rpmハードドライブ(ブートドライブ)の.dmgから読み取り、SATA-to-USBコネクタを介して接続された7200rpmドライブに書き込みます。私はデフォルトでブロックサイズを残しました、そして画像は約160GBです。

編集:そして、14時間の純粋なストレスの後、ddは結局完全に機能しました。ただし、次回はpvを介して実行し、straceを使用して追跡します。皆様のご協力に感謝いたします。

150
eckza

ddkillコマンドを使用して特定の信号を送信し、現在のステータスを出力させることができます。シグナルは、BSDシステム(OSXを含む)ではINFOであり、USR1 Linuxの場合。あなたの場合:

kill -INFO $PID

プロセスID($PID上記)psコマンドを使用;または、より便利な方法については mac os xのpgrepおよびpkillの代替案 を参照してください。

もっと簡単に言えば、 AntoineG彼の答え で指摘しているので、ctrl-Tシェルでddを実行してINFOシグナルを送信します。

Linuxの例として、次のようにすべてのアクティブなddプロセスの出力ステータスを作成できます。

pkill -USR1 -x dd

ステータスを出力した後、ddは対処を続行します。

176
Caleb

OS X(Linuxでは試さなかった)では、単純に次のように入力できます。 Ctrl+T ターミナルでddを実行しています。 kill -INFO $PIDと同じ出力と、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)

私はそれがこのスレッドを読んでいて、私のターミナルで新しいタブを開こうとしましたが、混合していることを知りました +T と Ctrl+T

104
AntoineG

ddの場合、 シグナルを送信 できます。ファイルの読み取りまたは書き込みを行っている他のコマンドについては、 lsof を使用してファイル内の位置を監視できます。

lsof -o -p1234    # where 1234 is the process ID of the command
lsof -o /path/to/file

事前に計画している場合は、データをパイプして pv を使用します。

より一般的な方法は、プログラムごとのディスクの読み取り/書き込みの現在の量を表示する iotop を使用することです。

編集:iotop -o現在I/O操作を実行するプログラムのみを表示します(このコメントに対して Jason C に感謝します)。

17
jofel

私は通常、そのような実行中のプロセスにstraceを付けます(-p $PIDオプション)システムコールでブロックされたままであるかどうか、またはまだアクティブであるかどうかを確認します。

または、実行中のddにシグナルを送信することに不安がある場合は、別のddを開始して、これが機能するかどうかを検証します。

13
philfr

次回は、最初からpvを使用できます(パッケージマネージャーから利用できる場合は、インストールしてください)。これは、入力を出力にパイプし、進行状況と速度を監視することを唯一の目的とするユーティリティです。

次に、イメージをドライブに書き込むために、4MBのブロックサイズを指定します。

pv -ptearb /path/to/image.bin | dd iflag=fullblock of=/dev/whatever bs=4M

最初のバッファリング(必要に応じてddを介して実行できる最終同期によってオフセットされる)の他に、これは進行状況バー、平均速度、現在の速度、およびETAを表示します。

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

実際にddpvを実行する順序は関係ありません。それは完全にパフォーマンスに関連しています。読み取りまたは読み取りを行うデバイスが、特定のブロックサイズに対して最適なパフォーマンスを持っている場合そのデバイスにアクセスするには、ddではなくpvを使用してください。必要に応じて、両端にddを貼り付けることも、気にしない場合はまったく貼り付けないこともできます。

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

coreutils v8.24以降、ddは進行状況の表示をネイティブでサポートしています。オプションstatus=progressを追加するだけです。

例:

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

ソース

ddrescueを実行すると、統計が表示されます。

デモ: http://www.youtube.com/watch?v=vqq9A01geeA#t=144s

5
Ben Preston

私はdcfldd(1)の使用を開始しました。これはdd操作をよりわかりやすく示しています。

4
Kartik M

ddプロセスのstderrストリームにアクセスできないため(たとえば、それが実行された端末がすでに閉じられているため)、INFOまたはUSR1信号を使用できない場合があります。この場合の回避策は次のことです(FreeBSDでテスト済み、Linuxでは多少異なる場合があります):

  1. iostatを使用して、ターゲットデバイスへの平均書き込み速度(MB /秒)を推定します。例:

    iostat -d -w30 ada0

    ここでada0をターゲットデバイス名に置き換え、それが2、3回結果を出すまで1分待ちます。 「w」パラメーターは、サンプル間の秒数を決定します。値を大きくすると、分散が少なく、より良い平均推定値が得られますが、より長く待つ必要があります。

  2. psを使用して、ddの実行時間を確認します。

    ps -xo etime,command | grep dd

    これを秒に変換して、ランタイムの合計秒数を取得します。

  3. ランタイムの合計秒数に平均書き込みレートを掛けて、転送された合計MBを取得します。
  4. デバイスサイズをMB単位で取得します。

    grep ada0 /var/run/dmesg.boot

    ada0をターゲットデバイス名に置き換えます。結果を平均書き込み速度で割り、合計転送時間を秒単位で取得します。残り時間を取得するには、これまで実行していた時間を差し引きます。

この戦略が機能するのは、ddが開始されてから現在の平均書き込み速度で継続的に書き込みを行っている場合のみです。他のプロセスがCPUまたはI/Oリソース(I/Oバスを含む)をめぐって競合している場合、転送速度が低下する可能性があります。

4
D Coetzee

progress を使用できます。これは特に、実行中のddの進行状況を示します。それは使用しています /proc/$pid/fdおよび/proc/$pid/fdinfo手動で監視することもできます。

3
jofel

ddの実行中に、これを別の端末でrootとして実行します。

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

1秒ごとにddステータスを出力します元のターミナルウィンドウ内ddが実行されており、コマンドが完了すると終了します。

2
ccpizza

_/proc/$pid/io_のwchar行(書き込まれた文字)は、ddプロセスに関する正確な情報を提供します。変更がある限り、ddは引き続き機能します。

以下は、きちんとした小さなphpスクリプトです。これを保存し、ddの実行中に_php filename.php_で実行して、書き込まれたバイトを表示できます。 kill -USR1 $(pidof dd)を介して_/proc/$pid/io_を監視する利点は、端末間を切り替える必要がないことです。これは必ずしもオプションではありません。

_<?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";
}
_
1
Leon Kramer