3

There are cases when I need to run a scheduled job in more complex way that Cron is able to provide. Say, to schedule a job to run every 23 or 65 minutes.

In the latter case it can be worked around by adding multiple Cron entries to run the same line. In the first case the number of lines to add becomes too much.

Three obvious solutions:

  • run the process every minute; use the job's its own logic to deduce when it should actually run and keep its state somewhere (say, in a file)
  • use "sleep" within script to pause for specified amount of time and keep it running using something like Supervisor
  • use any utility able to run a process periodically with arbitrary periods (such as a monitoring utility) and launch the task with it

but they all are inconvenient under certain circumstances.

Is there a smarter replacement for Cron, available at least for POSIX systems, able to use arbitrary schedules?

Konstantin Boyandin
  • 283
  • 2
  • 5
  • 16

2 Answers2

4

To run a job every 23 minutes the following won't work:

*/23 * * * * /some/command

As that will run on 00:00, 00:23 , then 23 minutes later again on 00:46 and then again on 01:00 which is 14 minutes later and not quite every 23 minutes.

The reason for that is that the / in */23 is not a mathematical "divide by" and does not match "whenever the number of minutes (since when? Midnight?) is a multiple of 23" .

*/23 is rather an "increments of". This tells cron to match every 23rd item (/23) from the set of minutes 0 1 2 3 4 5 6 7 8 9 10 11 ... 59 (for which * is the shorthand) i.e. minutes 0, 23 & 46.

That incremental behaviour also allows you to shift the off-set i.e. by starting the range at 1 rather than 0:

1-59/23 * * * * /some/command 

That job will now run every hour, 1 minute past, 24 minutes past and again 47 minutes past the hour.


I concur with your assessment that for odd schedules cron syntax is insufficient.

Cron is a very simple time driven scheduler.

I assume you probably want to run your job every 23 minutes because that is the the sum of the runtime of your batch job(s) and an added a bit of safety margin?

You choice is either simplify your scheduling needs such that they can work with cron, i.e. run your job every 30 minutes, or abandon that notion of time driven scheduling almost completely and investigate an event driven scheduler.

With an event driven scheduler the completion of one batch is the trigger to automatically start the next batch, optionally without delays and without running the risk you have with a time based scheduler that a batch starts before a previous batch has completed.

Wikipedia provides a comprehensive list of Job scheduler software or workload automation as many vendors like to call their products.

HBruijn
  • 77,029
  • 24
  • 135
  • 201
  • Thanks. OpenLava looks the closest match for the time being. – Konstantin Boyandin Apr 17 '16 at 05:50
  • 2
    If you don't want two instances running in parallel, then simply taking the usual runtime and adding a bit of safety margin is not sufficient. You need to decide what you want to happen if the job runs past the expected time (kill or wait) and implement that. I had a cron job which would usually run in 2 minutes. It was scheduled to start every hour. That sounds like a lot of saftety margin. But eventually I ran out of database connections because there were 50 instances of that job running in parallel. – kasperd Apr 17 '16 at 09:11
-3

run the command

crontab -e

Then, type in

2

if it asks you for a default editor Then, type in

*/23 * * * * <command here>

to run a job every 23 minutes. Replace 23 with any number you want.