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.
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 |
Thanks for the snippet. I was just banging my head against trap and sleep and this helped a lot!