Run only one instance of a program at a time
Lockfiles can provide race condition-free solutions
Scheduling jobs on cron is often a trial-and-error process but every, a command line app written in Perl makes it a lot easier.
You need to have cron, which comes with most Unix-based platforms (e.g. Linux, Mac OSX, BSD) and have Perl installed.
$ wget 'https://raw.github.com/iarna/App-Every/master/packed/every'
$ curl -O 'https://raw.github.com/iarna/App-Every/master/packed/every'
Save every to /usr/bin or add the parent directory to your PATH variable so you can run every from the command line.
The command to every to schedule a job takes the form: "every [num] unit program" (num defaults to one). So for example if you wanted to schedule a shell script to run every minute, type the following:
$ every minute script.sh
Which creates the following crontab:
SHELL=/bin/bash PATH=/home/sillymoose/perl5/perlbrew/bin:/home/sillymoose/perl5/perlbrew/perls/perl-5.16.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/home/sillymoose/.local/bin:/home/sillymoose/bin: */1 * * * * cd "/home/sillymoose"; script.sh
every translates the command into a new crontab entry and prints it on the command line. Helpfully it will set the SHELL variable and copy the user's PATH into the crontab. The icing on the cake is that every prepends a change directory command to ensure that cron executes the job from the script's parent directory. By doing these things, every eliminates (probably) the three most common causes of failed cron jobs.
Other units that every recognizes are: hour, day, week, month and the day of the week (e.g. Wednesday). The following are all valid every commands:
$ every 10 hours script.sh $ every mon script.sh $ every 3 months script.sh
One really cool feature of modern cron installs is that you can schedule a job to run on reboot. every also supports this:
$ every @reboot script.sh
every has more options than described above. Run "every --help" to see the full panoply of options.