Handling timeout properly
I love Sysadmin magazine, it has been my first exposure to lots of really good technologies. Which is why when I come across an oversight, I think it’s a terrible shame. I think this month’s Shell techniques article on handling timeout is missing the most useful technique - the unix alarm signal.
An alarm signal allows you to send a special signal to a running process after a given length, in order to handle the unintended or negative effects of time passing, such as users not interacting with your application in an intended time, or a network or inter-process communication failing to receive a response.
Handling an alarm signal in bash is the same as handling other signals - such as safely handling the stop signal which interrupts a process when you hit control and c.
You ‘catch’ an alarm signal in a bash script using ‘trap’ :
#!/bin/bash
sleep 5 && kill -s 14 $$ &
trap timeup 14timeup()
{
echo “Time up .. abort!”
exit 1
}for i in 1 2 3 4 5 6 7;
do
echo $i
sleep 1
done
Here the ’sleep’ command at the top that runs in the background forces the script to be completed within 5 seconds, otherwise an alarm event will be sent to the script. This is useful, it allows you as a sysadmin to create a script which handles a timeout differently to a deliberate introduction. A block which catches signal 2 demonstrates how this can look :
factory:~ andy$ sh dingdong.sh
1
2
^Cinterrupted !
factory:~ andy$ sh dingdong.sh
1
2
3
4
5
Time up .. abort!
Changing the first ’sleep’ line to a period greater than the time taken to currently run this script (e.g. 10 seconds) allows it to finish without one of these signals being generated.
factory:~ andy$ sh dingdong.sh
1
2
3
4
5
6
7
This technique is much more flexible than using read -t to handle timeout as it allows you to cause a more complex tidy-up procedure to be invoked when timeout is encoutered. You can also handle timeout of for example a dns lookup or wget, as well as user input.
Comments
One Response to “Handling timeout properly”
Leave a Reply
You must be logged in to post a comment.
August 19th, 2008 at 11:44 am
Your script is great! But you should do:
kill $!
at the end, to kill background sleep process. Otherwise, if your script ends without timeouting, bash still issues kill on the process which doesn’t exist now.