입력 크기만 미리 알려진 경우 파이프에서 명령 진행 상황을 어떻게 추적합니까?

입력 크기만 미리 알려진 경우 파이프에서 명령 진행 상황을 어떻게 추적합니까?

을 사용하여 느린 작업의 진행 상황을 추적하고 싶습니다 pv. 이 작업의 입력 크기는 미리 알려져 있지만 출력 크기는 알려져 있지 않습니다. 이로 인해 pv파이프 작업의 왼쪽에 배치해야 했습니다 .

문제는 장기 실행 명령이 버퍼링으로 인해 전체 입력을 즉시 소비한다는 것입니다. 이는 다음과 다소 유사합니다.파이프에서 버퍼링 끄기질문이지만 제 경우에는 생산 작업이 아닌 소비 작업이 느리고 이 경우 다른 질문에 대한 답변이 작동하지 않는 것 같습니다.

다음은 문제를 보여주는 간단한 예입니다.

seq 20 | pv -l -s 20 | while read line; do sleep 1; done
  20 0:00:00 [13.8k/s] [=====================================>] 100%

매초마다 업데이트되는 대신 진행률 표시줄이 즉시 100%로 점프하고 입력을 처리하는 데 걸리는 전체 20초 동안 그대로 유지됩니다. pv라인이 하나씩 처리되어야만 진행 상황을 측정할 수 있지만 마지막 명령의 전체 입력이 버퍼로 읽혀지는 것 같습니다.

알 수 없는 출력 라인 수를 보여주는 다소 긴 예:

#! /bin/bash
limit=10
seq 20 | \
  pv -l -s 20 | \
  while read num
do
  sleep 1
  if [ $num -gt $limit ]
  then
    echo $num
  fi
done

해결 방법에 대한 제안 사항이 있습니까? 감사해요!

답변1

설정에서 데이터는 pv오른쪽에서 처리되는 동안 전달되었습니다. pv다음과 같이 가장 오른쪽으로 이동하려고 할 수 있습니다 .

seq 20 | while read line; do sleep 1; echo ${line}; done | pv -l -s 20 > /dev/null

업데이트: 업데이트와 관련하여 가장 쉬운 해결책은 명명된 파이프와 하위 쉘을 사용하여 진행 상황을 모니터링하는 것입니다.

#! /bin/bash
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
(rm /tmp/progress.pipe; mkfifo /tmp/progress.pipe; tail -f /tmp/progress.pipe | pv -l -s 20 > /dev/null)&
limit=10
seq 20 | \
  while read num
do
  sleep 1
  if [ $num -gt $limit ]
  then
    echo $num
  fi
  echo $num > /tmp/progress.pipe
done

관련 정보