특정 dd 작업을 수행하고 전송의 "원시" 데이터를 다른 인터페이스(예: 터미널이 아닌)에서 전송에 대한 실시간 보기를 제공하기 위해 다른 것에 의해 폴링될 로그 파일에 추가하려고 합니다.
dd 작업은 다음과 같습니다.
dd if=/some/lvm bs=512K | gzip -c > /tmp/whatever
내가 볼 수 있는 가장 쉬운 방법은 명령을 파일에 출력하고 동시에 -SIGUSR1 pid로 종료하고 출력을 보는 것입니다. 하지만 프로세스의 pid를 변수에 저장하고 종료 명령에서 사용하는 방법을 찾을 수는 없습니다. .
나는 이것에 대한 하나 또는 두 개의 라이너를 보았습니다 .
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를 변수로 가져오는 방법을 잘 이해하지 못하기 때문에 파이프 출력을 사용하도록 수정할 수는 없습니다.
dd에 대한 대안을 보게 되어 기쁘지만 대부분은 동일한 행을 업데이트하는 dcfldd와 같이 더 복잡하지만 제 생각에는 저주와 같은 접근 방식입니다. 이로 인해 매초마다 해당 출력의 스냅샷을 찍고 필요한 데이터를 추출하기가 어렵습니다. 이를 처리할 수 있는 쉬운 방법이 있거나 "원시" 출력을 얻을 수 있다면 PV로 파이프할 수도 있습니다.
저를 계몽해주세요. ;-)
인사
편집: 그래서 "해결책"을 찾았습니다. 아직 예쁘지는 않지만
pgrep을 사용하여 프로세스 ID를 찾을 수 있으므로 dd 명령이 실행되어 파일로 출력될 때 watch -n1 'sudo kill -USR1 $(pgrep ^dd)'
매초 출력 전송 진행 상황을 실행하고 폴러가 해당 진행 상황을 해석할 수 있습니다.
이것은 여전히 우아한 해결책이 아니며 딜레마처럼 느껴집니다. 더 좋은 방법이 있다면 여전히 제안에 열려 있습니다. :-)
답변1
가장 좋은 대답은 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
답변2
트릭을 수행하는 스크립트는 다음과 같습니다.
(
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
답변3
아직도 이 문제를 발견할 수 있는 사람들을 위해:
dd의 진행 상황을 grep하거나 처리하려면 이를 괄호로 묶을 수 있습니다. kill에 의해 트리거된 출력은 stderr로 전송되므로 2>&1을 리디렉션하여 grepable로 만들 수 있습니다.
# ( DP=$(
dd if=/proc/kcore of=/dev/null bs=1M count=50000 &
echo $!); while kill -USR1 $DP 2>/dev/null; do sleep 1; done ) 2>&1 |grep copied
0 bytes copied, 1.73e-05 s, 0.0 kB/s
21043871744 bytes (21 GB, 20 GiB) copied, 1.01827 s, 20.7 GB/s
42920312832 bytes (43 GB, 40 GiB) copied, 2.02764 s, 21.2 GB/s
52428800000 bytes (52 GB, 49 GiB) copied, 2.49048 s, 21.1 GB/s
#
재미있게 만들려면 지퍼를 추가하세요. 브래킷이 더 필요할 거예요! gzip을 위해 >&1을 예약하려면 >&3을 우회해야 하기 때문입니다.
# ZIPFILE=/path/to/zipfile..
# ( DP=$(
((dd if=/proc/kcore bs=1M count=500 & echo $! >&3 ) | gzip > $ZIPFILE & ) 3>&1|head -1);
sleep 1 # wait for dd startup;
while kill -USR1 $DP 2>/dev/null ; do sleep 1; done) 2>&1|grep copied
241172480 bytes (241 MB, 230 MiB) copied, 1.00001 s, 241 MB/s
486539264 bytes (487 MB, 464 MiB) copied, 2.00568 s, 243 MB/s
524288000 bytes (524 MB, 500 MiB) copied, 2.16047 s, 243 MB/s
목적에 맞게 dd를 수정하세요.
추신. 이는 스크립트를 래핑한 다음 |grep 또는 스크립트 외부로 이동하는 작업의 일부입니다. 아니면 그 반대를 수행하고 한 줄에서 잘 작동합니다 :-)
답변4
그것이 당신에게 효과가 없다면 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