如果僅預先知道指令輸入的大小,如何追蹤管道中指令的進度?

如果僅預先知道指令輸入的大小,如何追蹤管道中指令的進度?

我想使用 來追蹤緩慢操作的進度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

更新: 關於您的更新,也許最簡單的解決方案是使用命名管道和子 shell 來監視進度:

#! /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

相關內容