Saturday, January 17, 2009

Bash Progress Bar

Ever wanted to show a progress bar on your bash scripts? I am talking specifically about the progress of file transfer or raw read scripts. It might be easier to explain with an example:

I have a script that reads raw data from a CD or DVD ROM disk and pipes that data to md5sum or sha1sum to find if the data on the disk matches the published md5sum or sha1sum checksums published by the vendor. I download ISOs and verify them before I send them to my customers.

I wanted to have the script show a progress bar so I started searching...

Here is how I have implemented clpbar

Installation instructions ( Fedora 10 x86_64 )
  1. Download and install clpbar ( bar-1.10.9.tar.gz ) -- See references at the end of this script.
  2. tar xvfz bar-1.10.9.tar.gz
  3. cd bar-1.10.9
  4. ./configure
  5. make
  6. su -c "make install"

Usage example

#!/bin/sh
#

# Start with verifying CDs
#

device="/dev/cdrom"
# pass the type of checksum into the script. (md5sum|sha1sum)
checksumtype=$1

#Find details of the device
blocksize=`isoinfo -d -i $device | grep "^Logical block size is:" | cut -d " " -f 5`
if test "$blocksize" = ""; then
echo catdevice FATAL ERROR: Blank blocksize >&2
exit 1
fi

blockcount=`isoinfo -d -i $device | grep "^Volume size is:" | cut -d " " -f 4`
if test "$blockcount" = ""; then
echo catdevice FATAL ERROR: Blank blockcount >&2
exit 1
fi


command="dd if=$device bs=$blocksize count=$blockcount conv=notrunc,noerror status=noxfer"

# find the mount point of the disk. In fedora we need to know this to get the exact
# size of the disk in bytes. Note: /dev/sr0 is the optical disk drive on my system.

mountpoint=`mount | grep /dev/sr0 | sed "s/\/dev\/sr0 on //g" | sed "s/\stype.*//g"`


# find the expected size of the media. In order for bar to display a progress
# bar we need to know the expected size in bytes.

expected_size=`du -bs "$mountpoint" | sed "s/\s.*//g"`


# execute the command to read the disk and
# pipe through bar with the size option set and
# pipe through md5sum or sha1sum

result=`$command | /usr/local/bin/bar -s $expected_size | $checksumtype`

# get the checksum only. ( get rid of the '- ' on the output. This is required
# for the python tool that actually executes this script and compares against
# my database of checksums. -- I use python to call this script and compare the results
# against those in database. Another option would have been to bash script the mysql portion too.

checksumresult=`echo $result | cut -d " " -f1`

echo $checksumresult



References:
Post a Comment