0

Is there a way to have a cron job automatically be rescheduled due to a special circumstance?

For a simplistic example, a holiday occurs and the payroll processing needs to run a day later than what is scheduled in cron

Can this be down through a script, config, environment variable, or would someone need to go in and manually make the change?

2 Answers 2

1

This is not something that is supported by cron. But it is possible to create a script to accommodate you question.

Going into your example, you should have some kind of agenda/list where the dates on which your process should run is stored.

Then you should make a crontab entry that runs daily a script that checks if the dates in the agenda/list matches. If not, do nothing. But if it has a match start the process.

0

For simple conditions, yes but for even moderately complex stuff you'll want to write a wrapper script around your payroll job.

For example, your cron job doesn't have to run the payroll processing program directly. It could (and probably should, if it isn't already) run it via a wrapper script.

say, a script called "myjob.sh", something like this:

#!/bin/bash

delayfile=/path/to/myjob.delay

if [ -e "$delayfile" ] ; then
  sleep $(cat "$delayfile)
  rm "$delayfile"
fi

# now set up whatever variables etc are needed and
# execute the actual payroll processing program

To delay the next (and only the next) run of the cron job by a day, you would just run something like the following (from the shell, as a user who has permissions to create that the file in that directory):

echo 86400 > /path/to/myjob.delay

The script fragment above assumes that the cron job isn't run daily - if it was then the next instance would run at about the same time that the sleep ends.

If the job was run daily, then you could do something like this instead:

#!/bin/bash

skipfile=/path/to/myjob.skip

if [ -e "$skipfile" ] ; then
  rm "$skipfile"
  exit 0
fi

# now set up whatever variables etc are needed and
# execute the actual payroll processing program```

If the skip file exists (e.g. if you run touch /path/to/myjob.skip in a shell), the script will delete it and exit immediately. The next run of the cron job will complete as normal.

These are very simple examples, just to give you the barest idea of what's possible. The script can do whatever it needs to do to check the condition(s), be as complex as required, run any external programs, look up an entry in a database, query a remote web server's json API, whatever.

You can do relatively simple stuff in cron itself, e.g. the above are simple enough that you could do them in cron:

weeky version:

00 01 * * 7 [ -e /path/to/myjob.delay ] && sleep $(cat /path/to/myjob.delay) && rm /path/to/myjob.delay && your-payroll-program

daily version:

00 01 * * * [ -e /path/to/myjob.skip ] && (rm /path/to/myjob.skip && exit 0) || your-payroll-program

IMO you're better off using a wrapper script - easier to read, easier to maintain, and you can use whatever scripting language you like, not just sh or bash. plus there's a limit to what you can reasonably do in a chain of logically and-ed/or-ed clauses, and a limit to what you can reasonably do in a one-liner before it becomes incomprehensible gibberish. It would be trivially easy to combine both the skip & delay features in a script, but quite difficult to do as a one liner or crontab entry.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .