Как я знаю, работает ли dd все еще?

\ No newline at end of file Вы добираетесь от GitHub, появляется в конце патча (в diff формат, см. примечание в конце раздела "Unified Format").

Компиляторы не заботятся, существует ли новая строка или не в конце файла, но gitdiff/patch утилиты), должны взять тех, которые в учетной записи. Существует много причин этого. Например, упущение добавить или удалить новую строку в конце файла изменило бы свой hashsum (md5sum/sha1sum). Кроме того, файлы являются не всегда программами и финалом \n мог бы иметь некоторое значение.

Примечание: О предупреждении от компиляторов C я предполагаю, что они настаивают для заключительной новой строки в целях обратной совместимости. Очень старые компиляторы не могли бы принять последнюю строку, если не заканчивается \n (или другая системно-зависимая последовательность символа конца строки).

148
04.06.2014, 22:49
14 ответов

Можно отправить dd определенный сигнал с помощью kill команда, чтобы заставить его произвести свой текущий статус. Сигнал INFO в системах BSD (включая OSX) и USR1 на Linux. В Вашем случае:

kill -INFO $PID

Можно найти идентификатор процесса ($PID выше) с ps команда; или см. pgrep и pkill альтернативы на Mac OS X для более удобных методов.

Проще, как AntoineG указывает в его ответе, можно ввести ctrl-T в оболочке, работающей dd для отправки это INFO сигнал.

Как пример на Linux, Вы могли сделать всех активными dd процессы производят состояние как это:

pkill -USR1 -x dd

После вывода его состояния, dd продолжит справляться.

175
27.01.2020, 19:28
  • 1
    , О, очень прохладный. Можно объединить тех, которые имеют pkill -USR1 -x dd –  Michael Mrozek♦ 13.04.2011, 20:26
  • 2
    @kivetros: В системах BSD необходимо отправить INFO сигнал. Linux не имеет SIGINFO и использования USR1 вместо этого. –  Gilles 'SO- stop being evil' 13.04.2011, 21:50
  • 3
    Сигналы SIGUSRx состоят в том, чтобы программы сделали то, что они хотят с, в противоположность наличию стандартизированного значения. SIGWINCH, например, повышен, когда терминал изменил свой размер, и программа, возможно, должна была бы перерисовать свой экран. Операционная система не отправляет SIGUSRx's, таким образом, они доступны для пользовательского использования. объем плазмы –  LawrenceC 14.04.2011, 04:17
  • 4
    Отправка dd USR1 сигнализирует также вскоре после того, как это запустилось (т.е. в сценарии удара, строка после запуска его) на самом деле завершит его. Поместите 0,1 вторых промежуточные сна, и они произведут свой прогресс правильно. Между прочим, очень хорошая команда dd для тестирования USR1/INFO на dd if=/dev/zero of=/dev/null. Интересный :) –  Lauritz V. Thaulow 14.04.2011, 11:51
  • 5
    BTW, все "истинные" BSDs отправляют SIGINFO группе приоритетного процесса, если символ состояния (Ctrl+T по умолчанию) отправляется на терминал. Но я не знаю, является ли этим верный для MacOSX. –  Netch 01.11.2012, 22:14

ddrescue даст Вам статистику, когда она работает.

демонстрация: http://www.youtube.com/watch?v=vqq9A01geeA#t=144s

5
27.01.2020, 19:28
  • 1
    Это могло бы быть полезно в следующий раз, но это не поможет OP понять, замораживается ли текущая команда или нет. –  Francesco Turco 02.11.2012, 15:11

Я обычно присоединяю strace к такому рабочему процессу (с -p $PID опция), чтобы видеть, остается ли это заблокированным в системном вызове или если это все еще активно.

Или, если Вы чувствуете себя озабоченными отправкой сигнала к выполнению dd, запустите другой dd, чтобы проверить, если это работает.

13
27.01.2020, 19:28
  • 1
    Как точно был бы Вы идти о присоединении strace? Кроме того, я действительно запускал другого dd и отправьте один из предложенных сигналов к нему, и... это уничтожило его. –  eckza 14.04.2011, 16:15
  • 2
    Если Вы знаете pid выполнения dd процесс, просто сделайте strace-p <pid>. Необходимо видеть журнал всех системных вызовов, названных процессом (главным образом чтение и запись) –  philfr 14.04.2011, 17:07

Для dd, можно отправить сигнал. Для других команд, которые читают или пишут в файл, можно наблюдать их положение в файле с lsof.

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

Если Вы планируете заранее, передаете данные по каналу через pv.

26
27.01.2020, 19:28
  • 1
    выглядит удивительным - я определенно собираюсь использовать тот следующий раз. Огромное спасибо. –  eckza 14.04.2011, 04:27
  • 2
    +1 - pv похож просто на билет. –  boehj 13.07.2011, 10:00

Более общий путь состоит в том, чтобы использовать iotop это отображает текущий объем чтения с диска / пишущий на программу.

Править: iotop -o шоу только программирует, которые в настоящее время работают, операции ввода-вывода (благодарит Jason C за этот комментарий).

17
27.01.2020, 19:28
  • 1
    Это - мой предпочтительный метод быстрой проверки также. iotop -o скроет процессы, которые не делают IO и помогают сказать сразу, что продолжается. –  Jason C 04.06.2014, 22:51

Под OS X (не примерял Linux), можно просто ввести Ctrl+T в терминальном выполнении dd. Это распечатает тот же вывод как kill -INFO $PID, плюс использование ЦП:

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.

101
27.01.2020, 19:28
  • 1
    О, хорошо, таким образом, load использование ЦП? –  pje 06.09.2014, 23:21
  • 2
    это было так лучшим решением! –  Stephn_R 18.03.2015, 07:41
  • 3
    , который я попробовал в dd на Linux, это просто, отзывается эхом ^T к терминалу. –  mwfearnley 06.01.2017, 16:48
  • 4
    удостоверяется, что Вы делаете ctrl+shift+T в –  JBaczuk 30.08.2017, 18:31

Иногда Вы не можете использовать ИНФОРМАЦИЮ или сигнал USR1 потому что stderr поток dd процесс не доступен (например, потому что терминал, в котором он выполнялся, был уже закрыт). В этом случае обходное решение должно сделать следующее (протестированный на FreeBSD, может немного отличаться на Linux):

  1. Использовать iostat оценить средний уровень записи (МБ/с) к целевому устройству, например:

    iostat -d -w30 ada0

    Замените своим названием целевого устройства ada0 здесь, и ожидайте минута его для предоставления пары результатов. "w" параметр определяет сколько секунд между образцами. Увеличение его даст лучшую среднюю оценку с меньшим различием, но необходимо будет ожидать дольше.

  2. Использовать ps определить сколько времени dd работал:

    ps -xo etime,command | grep dd

    Преобразуйте это в секунды для получения общих секунд времени выполнения.

  3. Умножьте общие секунды времени выполнения средним уровнем записи для получения общего переданного МБ.
  4. Получите размер устройства в МБ с:

    grep ada0 /var/run/dmesg.boot

    Замените своим названием целевого устройства ada0. Разделите результат на средний уровень записи для получения общего времени трансфера в секундах. Вычтите время, которое это выполняло до сих пор для получения времени, оставаясь.

Эта стратегия только работает если dd писал непрерывно на текущем среднем уровне записи, так как он начался. Если другие процессы конкурируют за ЦП или ресурсы ввода-вывода (включая шину ввода-вывода) затем, это может уменьшить скорость передачи.

4
27.01.2020, 19:28

В следующий раз вы можете просто использовать pv с самого начала (если это доступный через ваш менеджер пакетов, установите его). Это утилита с единственной целью - связывать входные данные с выходными, а также отслеживать прогресс и скорость.

Затем, для записи образа на диск, скажем, с размером блока 4 МБ:

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

Помимо начальной буферизации (смещение последней синхронизацией, которую можно выполнить с помощью dd , если хотите), это покажет вам индикатор выполнения, среднюю скорость, текущую скорость и расчетное время прибытия.

Параметр iflag = fullblock заставляет dd захватывать полные блоки ввода через pv , в противном случае вы зависите от конвейера для размеров блоков.

Чтобы пойти другим путем, используйте dd для чтения и pv для записи, хотя вы должны явно указать размер, если источник является блочным устройством. Для устройства 4 ГБ:

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 на обоих концах, если хотите, или вообще не использовать, если вам все равно:

pv -ptearb /path/to/image.bin > /dev/whatever
sync
11
27.01.2020, 19:28

WHAR Линия (письменные символы) в / proc / $ pid / io может дать вам точную информацию о dd процесс. Пока это меняется, ваш DD все еще работает!

Вот аккуратный маленький PHP-скрипт, который вы можете сохранить, а затем выполнить с помощью PHP filename.php во время DD , чтобы отобразить письменные байты. Приятное преимущество просмотра / proc / $ PID / IO all 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";
}
1
27.01.2020, 19:28

Я начал использовать dcfldd (1), который показывает dd операции лучшим способом.

4
27.01.2020, 19:28

Пока выполняется dd , я запускаю это в другом терминале как root:

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

Он печатает dd каждые 1 секунду в исходном окне терминала , где выполняется dd , и завершает работу, когда команда выполнена.

2
27.01.2020, 19:28

Начиная с coreutils v8.24, dd имеет встроенную поддержку для отображения прогресса. Просто добавьте параметр status = progress .

Пример:

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

Источник

10
27.01.2020, 19:28

Вы можете использовать progress который, в частности, показывает прогресс запущенного dd. Он использует /proc/$pid/fd и /proc/$pid/fdinfo, которые вы также можете отслеживать вручную.

3
27.01.2020, 19:28

Если вы записываете на медленный накопитель, например на USB-накопитель, вам может понадобиться знать не только ход выполнения самой команды dd, но также ход фактической записи на целевое устройство.

  • Один из способов узнать об окончании процесса — запустить syncпосле команды dd и подождать, пока она завершит очистку буферов, чтобы окно терминала вернулось к приглашению. Но индикации прогресса по-прежнему нет. Вы можете следить за ходом очистки, наблюдая за «грязными» данными, например, с помощью шелл-скрипта watch-flush, который является частью mkusb . Этот сценарий оболочки -использует данные из системного файла /proc/meminfo.

  • Проще модифицировать командную строку dd, чтобы она регулярно сбрасывала буферы, например, после записи каждого мибибайта, и в то же время показывала прогресс, например

    sudo dd if=file.img bs=1M of=/dev/sdx status=progress oflag=dsync
    

    Пожалуйста, проверьте и еще раз -проверьте правильность указания целевого устройства. В противном случае вы можете перезаписать ценные данные. ddделает то, что вы ему говорите, без вопросов, и по этой причине он получил прозвище «Разрушитель данных».

  • В Ubuntu и Debian вы также можете использовать mkusb для выполнения задачи клонирования. Он обмотает ремень безопасности вокруг dd:, поможет вам идентифицировать целевое устройство и позволит дважды -проверить его перед запуском процесса.

0
29.08.2020, 13:32

Теги

Похожие вопросы