
Me gustaría realizar un seguimiento del progreso de una operación lenta utilizando pv
. El tamaño de la entrada de esta operación se conoce de antemano, pero el tamaño de su salida no. Esto me obligó a ponerme pv
a la izquierda de la operación en la tubería.
El problema es que el comando de ejecución prolongada consume inmediatamente toda su entrada debido al almacenamiento en búfer. Esto es algo similar a laDesactivar el almacenamiento en búfer en la tuberíapregunta, pero en mi caso es la operación de consumo la que es lenta, no la de producción y ninguna de las respuestas a la otra pregunta parece funcionar en este caso.
A continuación se muestra un ejemplo sencillo que demuestra el problema:
seq 20 | pv -l -s 20 | while read line; do sleep 1; done
20 0:00:00 [13.8k/s] [=====================================>] 100%
En lugar de actualizarse cada segundo, la barra de progreso salta inmediatamente al 100% y permanece allí durante los 20 segundos que lleva procesar la entrada. pv
Solo podría medir el progreso si las líneas se procesaran una por una, pero toda la entrada del último comando parece leerse en un búfer.
Un ejemplo algo más largo que también demuestra el número desconocido de líneas de salida:
#! /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
¿Alguna sugerencia para una solución alternativa? ¡Gracias!
Respuesta1
En su configuración, los datos pasaron pv
mientras aún se procesan en el lado derecho. Podrías intentar moverte pv
hacia el lado derecho de esta manera:
seq 20 | while read line; do sleep 1; echo ${line}; done | pv -l -s 20 > /dev/null
Actualizar: Con respecto a su actualización, tal vez la solución más sencilla sea utilizar una canalización con nombre y un subshell para monitorear el progreso:
#! /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