10

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?

0

6 Answers 6

15

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:

looks like this

Sign up to request clarification or add additional context in comments.

3 Comments

I 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.sstatic.net/7JHnj.png
I think I solved it with changing DRAW to just DRAW(){echo -en "\033(0";} What was the echo -en "\033%"; for?
Can you please explain this solution?
7

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.

2 Comments

I shall have a look at this when I get home :) Cheers so far.
This 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!
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

Comments

1

Change the outer loop to:

pv /var/www/vhosts/domainlist | while read f
do
    ...
done

http://linux.die.net/man/1/pv

Or you can use any other program that provides a progress bar based on how much a file has been read.

4 Comments

I 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.
I 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.
It's probably because bash's read read whole input and then process it.
Would 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".
1

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

3 Comments

bash v4 is required for mapfile.
@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.
Yes, looks like it has 4.1: packages.ubuntu.com/lucid/bash
0

I suggest you to use Xdialog, Kdialog or zenity and it's progress option.

2 Comments

Forgot 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.
OK, then the pv is optimal solution.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.