¿Cómo agregar una barra de progreso a un script de shell?
Al escribir scripts en bash o cualquier otro shell en *NIX, mientras se ejecuta un comando que tardará más de unos pocos segundos, se necesita una barra de progreso.
Por ejemplo, copiar un archivo grande, abrir un archivo tar grande.
¿Qué formas recomienda para agregar barras de progreso a los scripts de shell?
Puede implementar esto sobrescribiendo una línea. Úselo \r
para volver al principio de la línea sin escribir \n
en la terminal.
Escribe \n
cuando hayas terminado para avanzar en la línea.
Úselo echo -ne
para:
- no imprimir
\n
y - para reconocer secuencias de escape como
\r
.
Aquí hay una demostración:
echo -ne '##### (33%)\r'
sleep 1
echo -ne '############# (66%)\r'
sleep 1
echo -ne '####################### (100%)\r'
echo -ne '\n'
En un comentario a continuación, puk menciona que esto "falla" si comienza con una línea larga y luego desea escribir una línea corta: En este caso, necesitará sobrescribir la longitud de la línea larga (por ejemplo, con espacios).
Quizás también te interese cómo hacer una ruleta :
¿Puedo hacer una ruleta en Bash?
¡Seguro!
i=1 sp="/-\|" echo -n ' ' while true do printf "\b${sp:i++%${#sp}:1}" done
Cada vez que el bucle se repite, muestra el siguiente carácter en la cadena sp, y continúa hasta llegar al final. (i es la posición del carácter actual que se mostrará y ${#sp} es la longitud de la cadena sp).
La cadena \b se reemplaza por un carácter de "retroceso". Alternativamente, puedes jugar con \r para volver al principio de la línea.
Si desea que se ralentice, coloque un comando de suspensión dentro del bucle (después de printf).
Un equivalente POSIX sería:
sp='/-\|' printf ' ' while true; do printf '\b%.1s' "$sp" sp=${sp#?}${sp%???} done
Si ya tiene un bucle que hace mucho trabajo, puede llamar a la siguiente función al comienzo de cada iteración para actualizar el control giratorio:
sp="/-\|" sc=0 spin() { printf "\b${sp:sc++:1}" ((sc==${#sp})) && sc=0 } endspin() { printf "\r%s\n" "$@" } until work_done; do spin some_work ... done endspin