dd show 'raw' progress while piping output

Я пытаюсь выполнить определенную операцию dd и добавить "сырые" данные передачи в файл журнала, который будет опрашиваться чем-то другим, чтобы обеспечить прямой просмотр передачи на другом интерфейсе (т.е. не терминале).

Операция dd выглядит так:

dd if=/some/lvm bs=512K | gzip -c > /tmp/whatever

Самый простой способ, который я вижу, это вывести эту команду в файл и одновременно выполнить kill -SIGUSR1 pid и просмотреть вывод, хотя я не могу найти способ сохранить pid процесса в переменной и использовать его в команде kill.

Я видел этот один два лайнера вокруг:

dd if=/some/lvm of=/some/fat/image/which/I/cant/use bs=512K& pid=$!; \
sleep 1; while [[ -d /proc/$pid ]]; do kill -USR1 $pid && sleep 1; done

Хотя я не очень понимаю, как он берет pid в качестве переменной, поэтому я не могу модифицировать его для работы с моим piped output.

Я с удовольствием смотрю на альтернативы dd, хотя большинство из них только усложняют задачу, например dcfldd, который обновляет одну и ту же строку с помощью какого-то метода, похожего на curses. Это затрудняет получение снимка этого вывода каждую секунду и извлечение нужных мне данных. Если есть простой способ справиться с этим или даже перевести в pv, если я могу получить "сырой" вывод.

Пожалуйста, просветите меня. ;-)

С уважением

EDIT: Итак, я нашел "решение", оно все еще не очень красивое, но

я могу использовать pgrep для поиска идентификатора процесса, так что пока команда dd выполняется и выводится в файл, я запускаю watch -n1 'sudo kill -USR1 $(pgrep ^dd)' для вывода прогресса передачи каждую секунду, который может быть интерпретирован poller'ом.

Это все еще не элегантное решение, и кажется, что это просто уловка. Если есть лучший способ, я все еще открыт для предложений :-)

0
28.02.2016, 19:54
3 ответа

Вот единственный сценарий, который должен выполнить цель:

(
        dd if=/some/lvm bs=512K &
        pid_dd=$!

        while :; do
                sleep 1
                kill -USR1 $pid_dd
        done &
        pid_monitor=$!

        wait $pid_dd
        kill $pid_monitor
) |
        gzip -c > /tmp/whatever
0
28.01.2020, 02:49

Лучший ответ - pv , который позволяет вам видеть прогресс любого процесса, который вы можете передать.

dd if=/some/lvm bs=512K | pv | gzip -c > /tmp/whatever

Вы даже можете использовать это для типичного использования dd для создания или записи образов дисков путем подключения dd к самому себе через pv :

dd if=/dev/cdrom | pv | dd of=/path/to/some.iso
1
28.01.2020, 02:49

Если вы не можете использовать pv, вы на правильном пути с kill -USR1. Учитывая вашу начальную команду dd if=/some/lvm bs=512K | gzip -c > /tmp/whatever, я бы сделал что-то вроде этого в контексте пары сценариев:

dd if=/some/lvm bs=512K | gzip -c > /tmp/whatever &
PID=$! # $! is set to the PID of the last backgrounded process
echo $PID > /var/run/dd_pid.txt  # So that other scripts can read it
fg
rm /var/run/dd_pid.txt

Тем временем, в другом сценарии:

PID=$(cat /var/run/dd_pid.txt)
if [[ 0 -ne $? ]]; then
    echo 'PID file not found'
    exit 1
fi
while kill -0 $PID; do
    sleep 1
    kill -USR1 $PID
done
0
28.01.2020, 02:49

Теги

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