Jaws… A Bash Script progress bar

Back in about 1987, I started working for a very small company running out of offices on London’s South Bank -hence their name, SouthBank Systems PLC. They wrote specialist, database-based applications for local councils and their contractors to manage how their parks, street trees and other amenity values should be maintained.

I learnt so much in that job -that Bowling Greens are about the most expensive piece of grass you can ever install, per square meter, for example. Or that, if you make the mistake of writing your code this way, it is easy to generate “random inspection lists” that send an inspector first to one site, then a second on the other side of the borough, then back to a third… which was adjacent to the first! Who knew that what they really needed was a random selection of sites that were then sorted into an ordered, walkable path. Well, we did eventually: but it took us a while before the penny dropped!

One of the first-ever training sessions I ever gave took place in a greenhouse in Aldershot, where the contractors were bemused by the two minutes of frenetic activity they’d seen me do before turning to them to speak. They wanted to know what I’d done, because it looked interesting. It took a moment for me to work out what they were intrigued by, but yeah: they wanted to know how to switch a computer on and what happens when you do. I learnt how to read audience expectations  that day!

Anyway, one of the little features of our software we were quite proud of, and which the clients loved, was Jaws. He was simply a shark fin that paced up and down the screen, letting you know that stuff was happening in the background. These days we call them progress bars and don’t think much about them, but to the kind of people I was working with back then, the “personality” of the progress bar was important.

I’d therefore like to present you with my 25-year tribute to Jaws, The SouthBank Systems progress bar, as implemented in Bash, as follows:

function jaws() {
i=1
char=">"
pos=4
while true
do
 i=$((i+1))
 if [ $(($i%60)) -eq 0 ]; then
 if [ "$char" = ">" ]; then
 char="<"
 else
 char=">"
 fi
 fi
 if [ "$char" = ">" ]; then
 pos=$((pos+1))
 if [ "$pos" -gt 60 ]; then
 pos=60
 fi
 else
 pos=$((pos-1))
 if [ "$pos" -lt 5]; then
 pos=5
 fi
 fi
 tput cup 18 5; echo "............................................................";
 tput cup 18 $(($pos)); echo -n $char;tput cup 20 5
 sleep 0.2
done
}

The variable “i” forever increments. But we pick a point when its value can be tested. In this case we check whether i modulus 60 is zero. (that is, can “i” be devided by 60 without leaving any remainder). If it is, then we use that to trigger a change in the progress bar character from “>” to “<”. Additionally, if we are left with “>” as our character, then we know to keep on incrementing the position where that character should be displayed. If we acquire a “<”. then the position counter will be decreased.

So you stick that function at the top of your bash script somewhere, and then it comes time to use it. Here’s the simplest case:

jaws &
jawsp=$!
sleep 40
kill $jawsp &>/dev/null

The “thing” this script is doing is simply to sleep for 40 seconds, but it could be doing any meaningful work. The point is that before the work starts, you invoke the jaws function -with an ampersand character (&) to make it run in a new, background session. We assign the process ID of that new session to a jawsp variable. When our sleep/work has finished, we can kill that process, which will stop the shark fins parading up and down the screen.

Eighties tribute bands are seldom worth the price of admission and it is similarly likely that you will consider Jaws a not very exciting addition to your set of Bash scripting skills. You may indeed be bemused that there was a highly professional set of clients and staff who thought Jaws was one of our most valuable bits of IP (shocking, but true, I fear). But even if it’s as welcome as a Mama Mia reunion ‘do’ at the Hammersmith Palais on a wet Wednesday night, I’m going to let you watch the video anyway because, for me, he brings back happy memories when my database skills extended to re-building DataFlex indexes and showing gardeners how to turn on a PC. Happy times!

Sharkfinsoup

Coming soon to a Gladstone shell script near you shortly, of course…

And cheers to Chris Megan, who wrote the original, all those moons ago.

Print Friendly

5 thoughts on “Jaws… A Bash Script progress bar

  1. holger

    line 23 seems to be gobbled up: instead of

    if [ "$pos" -lt 5]‘ then

    it should rather read

    if [ "$pos" -lt 5 ]; then

    And I’m sorry that I don’t know how properly format code in a comment. It’s good reading you again (just stumbled over your blog today searching for conky).
    Cheers
    Holger

    Reply
  2. Chris Megan

    Howzit You Smooth Blogging Dude Dowunder,

    I am deeply honoured by those kind comments.

    I am also pleased that your prose continues, although, way over my head nowadays. How about some non-geeky output to balance it up…

    Here’s a little something I threw together this year for Burning Man…
    http://www.youtube.com/watch?v=u00OF3ilNUs

    You welcome in Cape Town, anytime, dear Howard…

    Reply
  3. joel garry

    And for some really useless use, it can be run in older ksh (that doesn’t have < 1 second sleep) by simply removing the parens in the first line, and substituting the sleep with some slowdown like

    while [ $j -lt 50 ]
    do
    j=`expr $j + 1`
    done

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>