dd가 여전히 작동하는지 어떻게 알 수 있습니까?


147

나는 dd그다지 많이 사용 하지는 않았지만 지금까지는 여전히 실패하지 않았습니다. 지금은 dd12 시간 넘게갔습니다. 디스크에서 이미지를 다시 쓰고 dd있습니다. 디스크에서 이미지 로 갈 수 있었기 때문에 조금 걱정이되었습니다. 7 시간

4GB RAM의 2.1ghz / core에서 Core 2 Duo가 장착 된 MacBook에서 OSX 10.6.6을 실행하고 있습니다. 7200rpm 하드 드라이브 (부팅 드라이브)의 .dmg를 읽고 SATA-to-USB 커넥터를 통해 연결된 7200rpm 드라이브에 쓰고 있습니다. 기본적으로 블록 크기를 그대로두고 이미지는 약 160gb입니다.

편집 : 그리고 14 시간의 순수한 스트레스 dd후에 결국 완벽하게 작동했습니다. 다음 번에는을 통해 pv추적하고 추적 할 것입니다 strace. 모든 도움을 주셔서 감사합니다.


7
귀하의 질문에 대답하지 않지만 귀하의 시간은 상당히 높은 IMO입니다. 기본 512 바이트가 아닌 dd에 더 큰 블록 크기를 전달하는 것을 기억 했습니까? dd ... bs=16MRAM, 디스크 크기 및 속도를 감안할 때 제 제안입니다.
Juliano

나는 그것을 안전하게 플레이하기를 원했기 때문에하지 않았습니다. 그래도 다음에 시도하겠습니다. 감사.
eckza

내 경험상 ddMac OS X에서는 프로세스를 죽일 수는 없지만 시스템을 다시 시작 해야하는 시점까지 멈추는 경향이 있습니다. 나는 그때 리눅스 VM에서 일하는 것에 의지한다.
ssc

답변:


173

명령을 dd사용하여 특정 신호를 보내 kill현재 상태를 출력 할 수 있습니다. 신호는 INFOBSD 시스템 (OSX 포함) 및 USR1Linux에 있습니다. 귀하의 경우 :

kill -INFO $PID

명령으로 프로세스 ID ( $PID위)를 찾을 수 있습니다 ps. 보다 편리한 방법 은 mac OS x에서 pgrep 및 pkill 대안을 참조하십시오 .

더 간단히 말하면 AntoineG그의 답변 에서 지적한 것처럼 ctrl-Tdd를 실행하는 쉘에 입력 하여 INFO신호 를 보낼 수 있습니다.

Linux의 예로 모든 활성 dd프로세스 출력 상태를 다음과 같이 만들 수 있습니다 .

pkill -USR1 -x dd

상태를 출력 한 후에 dd는 계속 대처합니다.


9
아 정말 멋지다 다음과 결합 할 수 있습니다pkill -USR1 -x dd
Michael Mrozek

9
@kivetros : BSD 시스템에서는 INFO신호 를 보내야합니다 . Linux에는 SIGINFO가 없으며 USR1대신 사용 합니다.
Gilles

5
SIGUSRx 신호는 표준화 된 의미가 아니라 프로그램이 원하는 것을 수행하기위한 것입니다. 예를 들어 SIGWINCH는 터미널의 크기가 변경되어 프로그램이 화면을 다시 그려야 할 때 발생합니다. 운영 체제는 SIGUSRx를 보내지 않으므로 사용자 지정 용도로 사용할 수 있습니다.
LawrenceC

11
USR1 신호 를 시작한 후 너무 빨리 dd를 보내면 (즉, bash 스크립트에서 시작한 줄) 실제로 종료됩니다. 0.1 초 동안 절전 모드를 설정하면 진행 상태가 올바르게 출력됩니다. 그건 그렇고, USR1 / INFO를 테스트하는 아주 좋은 dd 명령은 dd if=/dev/zero of=/dev/null입니다. :)
Lauritz V. Thaulow

11
BTW, 모든 "true"BSD는 상태 문자 (기본적으로 Ctrl + T)가 터미널로 전송되면 SIGINFO를 포 그라운드 프로세스 그룹으로 보냅니다. 그러나 MacOSX에 해당되는지 여부는 모르겠습니다.
Netch

100

OS X (Linux에서는 시도하지 않았 음) 에서 터미널을 실행하는 터미널에 Ctrl+ T를 입력 하면됩니다 dd. kill -INFO $PIDCPU 사용량과 동일한 출력을 인쇄합니다 .

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)

이 스레드를 읽고 터미널에서 새 탭을 열려고하지만 + TCtrl+를 혼합하려고한다는 것을 알았습니다 T.


1
오, loadCPU 사용량도 그래요?
pje

이것은 훨씬 더 나은 해결책이었습니다!
Stephn_R

Linux에서 dd로 시도했지만 ^T터미널에 에코 됩니다.
mwfearnley

1
Mac 터미널에서 ctrl + shift + T를 수행하고 있는지 확인하십시오
JBaczuk

26

대해 신호를 보낼dd 수 있습니다 . 파일을 읽거나 쓰는 다른 명령의 경우을 사용하여 파일에서 해당 위치를 볼 수 있습니다 .lsof

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

미리 계획하는 경우 데이터를 통해 파이프하십시오 pv.


1
pv는 놀랍습니다-나는 확실히 다음에 사용할 것입니다. 정말 고맙습니다.
eckza

1
+1- pv티켓처럼 보입니다.
boehj

17

보다 일반적인 방법은 iotop프로그램 당 현재 디스크 읽기 / 쓰기 양을 표시하는 것입니다.

편집 : iotop -o현재 I / O 작업을 수행하는 프로그램 만 표시하십시오 ( 이 의견 에 Jason C 감사합니다 ).


1
이것은 내가 선호하는 빠른 확인 방법이기도합니다. iotop -oIO를 수행하지 않는 프로세스를 숨기고 진행 상황을 한눈에 더 쉽게 알 수 있습니다.
Jason C

13

나는 일반적으로 시스템 호출에서 차단 된 상태로 남아 있는지 또는 여전히 활성 상태인지 확인하기 위해 strace실행중인 프로세스 ( -p $PID옵션 포함)에 연결합니다.

또는 실행중인 dd에 신호를 보내는 것이 긴장된 경우 다른 dd를 시작하여 작동하는지 확인하십시오.


2
정확히 어떻게 첨부 strace하시겠습니까? 또한, 나는 또 다른 것을 시작 dd하고 제안 된 신호 중 하나를 보내서 죽였습니다.
eckza

2
실행중인 dd 프로세스의 pid를 알고 있다면 strace -p <pid>를 수행하십시오. 프로세스가 호출 한 모든 시스템 호출의 로그 (대부분 읽기 및 쓰기)가 표시되어야합니다.
philfr

11

다음에 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

정말 당신이 어떤 순서는 중요하지 않습니다 dd그리고 pv당신이 나에서 읽고있는 장치가 사용하려는 특정 blocksizes 최적의 성능이있는 경우 -에, 그것은 전적으로 성능 관련의 dd대신 pv해당 장치에 액세스 할 수 있습니다. 당신도 붙어 있습니다 dd당신은 상관하지 않는 경우 모두에서 전혀 당신이 원하는 경우 종료 여부 :

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

10

현재 coreutilsv8.24, dd진행률을 표시에 대한 기본 지원합니다. 옵션을 추가하십시오 status=progress.

예:

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

출처



4

dd프로세스 의 stderr 스트림에 액세스 할 수 없기 때문에 (예 : 실행 된 터미널이 이미 닫혀 있기 때문에) INFO 또는 USR1 신호를 사용 하지 못할 수 있습니다. 이 경우 해결 방법은 다음을 수행하는 것입니다 (FreeBSD에서 테스트되었으며 Linux에서는 약간 다를 수 있음).

  1. iostat대상 장치에 대한 평균 쓰기 속도 (MB / s)를 추정하는 데 사용 합니다 (예 :

    iostat -d -w30 ada0

    ada0여기에 대상 장치 이름을 대체 하고 몇 가지 결과가 나올 때까지 잠시 기다리십시오. "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

dd 작업을 더 잘 보여주는 dcfldd (1)를 사용하기 시작했습니다.


2

dd실행 하는 동안 다른 터미널에서 루트로 이것을 실행합니다.

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

실행중인 원래 터미널 창 에서 dd1 초마다 상태를 인쇄하고 명령이 완료되면 종료됩니다.dd


너무 멋지다. El Capitan
Stefano Mtangoo

2

progress특히 달리기의 진행 상황을 보여주는 것을 사용할 수 있습니다 dd. 그것은 사용 /proc/$pid/fd하고 /proc/$pid/fdinfo 당신은 또한 손으로 모니터링 할 수 있습니다.


1

wchar라인 (기록 된 문자)에서는 /proc/$pid/io당신에게에 대한 정확한 정보를 제공 할 수 있습니다 dd과정을. 변경 dd되는 한 계속 작동합니다!

여기에 저장 한 다음에 실행할 수있는 깔끔한 작은 PHP 스크립트입니다 php filename.php(가) 동안 dd기록 된 바이트를 표시합니다. 시청의 좋은 장점 /proc/$pid/io이상은 kill -USR1 $(pidof 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";
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.