Я пытаюсь выполнить определенную операцию 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'ом.
Это все еще не элегантное решение, и кажется, что это просто уловка. Если есть лучший способ, я все еще открыт для предложений :-)
Вот единственный сценарий, который должен выполнить цель:
(
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
Лучший ответ - 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
Если вы не можете использовать 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