Last Updated: February 25, 2016
·
1.679K
· jamesmartin

Run a Shell Script for the Duration in Unix

Previously, we looked at calculating durations using the Unix built-in expr function.

Another common task in shell scripting is running some code repeatedly for a given duration.

Consider the following example, wherein we specify a URL to fetch and check that it returns an HTTP 200 ‘OK’ response:

#!/bin/bash

url='http://www.google.com'

while true; do
  status=`curl -o /dev/null --silent --write-out '%{http_code}\n' $url`
  if [ ! "$status" = "200" ]; then
    echo "Everything is not OK: $url returned $status"
  fi
done

We can run this script and it will ping the Google homepage indefinitely. We could leave it running for a while and then come back later to see if any failures had occurred.

Consider the following simple modifications to allow the user of our script to specify a maximum duration, in seconds:

#!/bin/bash

url='http://www.google.com'

starttime=$(date +%s)
endtime=$(expr $starttime + $1)

while [ $starttime -lt $endtime ]; do
  status=`curl -o /dev/null --silent --write-out '%{http_code}\n' $url`
  if [ ! "$status" = "200" ]; then
    echo "Everything is not OK: $url returned $status"
  else
    printf "%s" "."
  fi
  let starttime=$(date +%s)
done

First we use the date +%s function to set a starttime variable in seconds since the Epoch. We calculate an endtime by adding the user-supplied duration (in seconds) to the starttime.

Next we start our loop running, but constrain to only continue running while our starttime is less than our endtime.

Inside the loop we add a little printf "%s" "." to the else condition, to give our user an indication that the script is still alive.

Finally, just before the end of the while loop, we update our starttime variable to prevent the script looping forever.

Among other things, this kind of script reminds me that the tenets of the old Unix philosophy — 'small is beautiful' and 'do one thing well', among others — still very much hold true.