Today I’m going to talk about three things; two fairly common, and the third not so common. Two are solved with the same script, while the third is a separate include.
The problems addressed are the following:
- Making sure that only one copy of a script can be active at a time
- Limiting the run time of a script
- Having a script run multiple times, usually within a minute
There are two files attached to this blog. They are:
script_timer.sh (5.0 KiB, 452 hits)
onlyRunOnce (794 bytes, 583 hits)
Put both scripts into the same directory; I usually put them in /usr/local/bin.
This contains a small bash function called (oddly enough) onlyRunOnce, which addresses the first problem of only allowing one instance of the script to be active at any time. To use it, simply put the following 2 lines at the beginning of a bash script:
. ./onlyRunOnce onlyRunOnce
This will check to make sure that the script isn’t currently running; if it is, it just exits. If you want a message displayed when it exits, just add a parameter to the function call as follows:
The value parameter doesn’t matter, it only checks for the presence of it. Currently it puts the log files in /tmp, that can be easily changed by editing the line where LOCKDIR is defined.
While not necessary, it is nice to cleanup when you are done. So there is a second function called:
which simply removes the lock file. Call this function at the end of your script.
This is designed to run once a minute from cron.
It will run a specified program or script multiple times per minute, prevent a program or script from running too long, and will send an email if it either exits with a non-zero error or exceeds the timeout.
There are a number of options which can be set. All of these options can be set either by the command line or by setting variables inside the escript.
To use it, put it into a cronjob using the following syntax:
/usr/local/bin/script_timer.sh [-m maxWaitTime] [-t totalRunTime] [-c checksPerRun] [-l logfile] [-s script] [-e emailto] [-n notifyon] [-x maxEmails] [-1] [-d] [-?]
|Maximum time to wait for a script to execute before killing it|
|Maximum time for this script to run|
|How many times to do the checks during the TOTALRUNTIME|
|File to log to|
|Program or script to run. Be sure to specify the full path to be safe|
|Address(s) to send messages to. If multiple addresses, put them inside quotes and comma separated.|
|Email on either any non-zero error, or 137 (which results from a kill). Acceptable values are: nonzero or 137|
|Maximum number of emails to send out during a run.|
|Only allow a single instance to be active|
|Debug mode. Print all values and exit|
|Print short usage and exit|
The following is an example of how to use it inside a crontab file:
# This doesn't do anything special, it just runs the script using the default. # The defaults, if not changed, will simply run the script: * * * * * /usr/local/bin/script_timer.sh -s testscript.sh
# Run once every minute, waiting a max of 5 seconds, checking 3 times during the run, which # effectively means that the testscript will be run once every 20 seconds: * * * * * /usr/local/bin/script_timer.sh -s testscript.sh -m 5 -c 3 -t 60 -e "email@example.com" -n 137 -1 # Run once every 5 minutes, waiting a max of 5 seconds, checking 10 times during the run, # which effectively runs the testscript once every 30 seconds */5 * * * * /usr/local/bin/script_timer.sh -s testscript.sh -t 300 -c 10 -m 5