Bash scripting, traps and sleep

Today I ran into any old problem: you have a script that should do something when it recieves a signal (e.g. if someone sends it USR1 it should write to a log/syslog), but the script uses a long sleep because it normally only checks/calculates stuff every x min. If you send it a kill -USR1 $pid it will normally execute the trap AFTER the sleep is done, not so great. I figured of the following solution today: put the sleep in a while loop that checks if the full time was slept, and inside the loop a sleep that sleeps the X seconds remaing in the background followed by a wait.

If the script now recieves a USR1 it can kill the wait, execute the trap and will continue the remaining sleep on the next iteration of the loop.

Select All bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#!/bin/bash
 
initialize() {
set -o nounset
trap cleanup INT TERM EXIT
trap print_foo USR1
}
 
cleanup() {
exit 0
}
 
print_foo() {
echo "foo"
}
 
initialize
 
# sleep 1 min
SLEEPTILL=$(date '+%s' --date="+1 min")
 
while [[ $(date '+%s') -lt ${SLEEPTILL} ]]
do
sleep $(bc <<< "${SLEEPTILL} - $(date '+%s')") &
BACKGROUND=$!
wait $BACKGROUND
done


Trackback URL

  1. Brian
    19/10/2009 at 5:46 pm Permalink

    Thanks for the snippet. I was just banging my head against trap and sleep and this helped a lot!