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.