Bash progress bar
Solution 1
Here's a fancy progress bar that you might enjoy...
#!/bin/bash
# Slick Progress Bar
# Created by: Ian Brown ([email protected])
# Please share with me your modifications
# Functions
PUT(){ echo -en "\033[${1};${2}H";}
DRAW(){ echo -en "\033%";echo -en "\033(0";}
WRITE(){ echo -en "\033(B";}
HIDECURSOR(){ echo -en "\033[?25l";}
NORM(){ echo -en "\033[?12l\033[?25h";}
function showBar {
percDone=$(echo 'scale=2;'$1/$2*100 | bc)
halfDone=$(echo $percDone/2 | bc) #I prefer a half sized bar graph
barLen=$(echo ${percDone%'.00'})
halfDone=`expr $halfDone + 6`
tput bold
PUT 7 28; printf "%4.4s " $barLen% #Print the percentage
PUT 5 $halfDone; echo -e "\033[7m \033[0m" #Draw the bar
tput sgr0
}
# Start Script
clear
HIDECURSOR
echo -e ""
echo -e ""
DRAW #magic starts here - must use caps in draw mode
echo -e " PLEASE WAIT WHILE SCRIPT IS IN PROGRESS"
echo -e " lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk"
echo -e " x x"
echo -e " mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj"
WRITE
#
# Insert your script here
for (( i=0; i<=50; i++ ))
do
showBar $i 50 #Call bar drawing function "showBar"
sleep .2
done
# End of your script
# Clean up at end of script
PUT 10 12
echo -e ""
NORM
looks like this:
Solution 2
You can use pv
but the other way.
for ... # outer loop
do
...
echo -n X
done | pv -s $(wc -l 'your_file_list') - >/dev/null
so you use echo X
to say when another portion of work is done and this is counted
by pv, it's know what the whole job size is due to -s
option.
Solution 3
You could use something like:
progress(){
# example usage:
# progress 30G 9G 30
# 30G [================>.................................] 30% (9G)
# params:
# $1 = total value (e.g.: source size)
# $2 = current value (e.g.: destination size)
# $3 = percent completed
[[ -z $1 || -z $2 || -z $3 ]] && exit # on empty param...
percent=$3
completed=$(( $percent / 2 ))
remaining=$(( 50 - $completed ))
echo -ne "\r$1 ["
printf "%0.s=" `seq $completed`
echo -n ">"
[[ $remaining != 0 ]] && printf "%0.s." `seq $remaining`
echo -n "] $percent% ($2) "
}
from https://gist.github.com/ivanalejandro0/9159989
You can see an usage example in https://github.com/ivanalejandro0/misc/blob/master/shell-scripts/copy-progress.sh
Solution 4
Change the outer loop to:
pv /var/www/vhosts/domainlist | while read f
do
...
done
Or you can use any other program that provides a progress bar based on how much a file has been read.
Solution 5
Given that you mentioned in a comment that you're on a debian based system, you could use whiptail
. When you install a deb package that requires configuration, text-based windows are drawn to ask you stuff; that's whiptail
.
Something like
#!/usr/bin/env bash
# mapfile requires bash 4
mapfile -t domains < /var/www/vhosts/domainlist
# for older bash versions, read can be used in this case.
#IFS=$'\n' read -rd '' -a domains < /var/www/vhosts/domainlist
n=${#domains[@]}
for ((i=0; i < n; ++i)); do
printf 'XXX\n\n%s\nXXX\n' "Checking ${domains[i]}"
if whois "${domains[i]}" | grep -Fiq domainregistrar; then
printf '%s\n' "${domains[i]}" >&3
else
printf '%s\n' "${domains[i]}" >&4
fi
printf '%d\n' $((100*i/n))
done 3>our_registrar 4>external_registrar | whiptail --gauge "" 6 50 0
![Zippyduda](https://i.stack.imgur.com/o6Q5T.png?s=256&g=1)
Zippyduda
Updated on June 04, 2022Comments
-
Zippyduda about 2 years
I'm using the following script to go through a large list of domains in whois and find the registrar (useful for server/DNS migrations) and it works fine.
However I am wanting to incorporate a progress bar into it just for the sake of convenience. Here's my script, if it can be improved let me know:
#!/bin/bash for f in `cat /var/www/vhosts/domainlist` do if domain=$f [ "$domain" ] ; then whois $f | grep -i domainregistrar > /dev/null if [ $? -le 0 ] ; then echo $f >> our_registrar else echo $f >> external_registrar fi fi done echo "Done, check our_registrar file."
I've tried this first: http://moblog.bradleyit.com/2010/02/simple-bash-progress-bar-function.html
And then this but with no luck.
What do you reckon is the easiest way to get a progress bar implemented into that script?
-
Zippyduda almost 12 yearsForgot to say, (not sure if relevant), on an Ubuntu 10.04 box with only SSH, no GUI. Those seem directed towards ones with a GUI, however I imagine due to it being unix it all applies down to SSH anyway.
-
igustin almost 12 yearsOK, then the pv is optimal solution.
-
Zippyduda almost 12 yearsI placed that line in it, the script still works however it goes to 100% with the bar full immediately: ./findregistrar.sh 1.12kB 0:00:00 [30.4MB/s] [==================================================================================================>] 100% so it has not worked correctly. It sits at the blank cursor which is normal until completed, then when done obviously it says: Done, check our_registrar file. But not clear on why it is not working.
-
Zippyduda almost 12 yearsI have a feeling it is due to it not knowing what 25/50/75/100 is actually defined by and when it has reached a % stage.
-
nshy almost 12 yearsIt's probably because bash's read read whole input and then process it.
-
Zippyduda almost 12 yearsWould it help if I got it to calculate how many lines are in the file, divide this by 10 and tell it when =>X (or <=X ) amount of lines has completed, that is 10% and do a line count/check and then once it has completed each line get it to say "complete".
-
Zippyduda almost 12 yearsI shall have a look at this when I get home :) Cheers so far.
-
jordanm almost 12 yearsbash v4 is required for mapfile.
-
geirha almost 12 years@jordanm, good point. I'm fairly certain Ubuntu 10.04 has bash 4, but I updated the answer with an alternative for older bash versions anyway.
-
jordanm almost 12 yearsYes, looks like it has 4.1: packages.ubuntu.com/lucid/bash
-
rubo77 over 10 yearsI get a strange unicode-sign at the top-left corner for the %:
% PLEASE WAIT WHILE SCRIPT IS IN PROGRESS
how can I remove that? screenshot: i.stack.imgur.com/7JHnj.png -
rubo77 over 10 yearsI think I solved it with changing DRAW to just
DRAW(){echo -en "\033(0";}
What was theecho -en "\033%";
for? -
Jon Gjengset over 10 yearsThis is pretty neat, but bear in mind that it puts the for-loop in a subshell, and so any changes you make to variables inside the loop won't affect variables outside the loop!
-
Shammel Lee about 7 yearsCan you please explain this solution?