명령 입력의 크기만 미리 알려진 경우 파이프라인에서 명령 진행 상황을 어떻게 추적할 수 있나요?

명령 입력의 크기만 미리 알려진 경우 파이프라인에서 명령 진행 상황을 어떻게 추적할 수 있나요?

느린 작업의 진행 상황을 추적하는 데 사용하고 싶습니다 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

관련 정보