21

I have the following general question regarding cron jobs.

Suppose I have the following in my crontab:

* 10 * * * * someScript.sh
* 11 * * * * someScript2.sh
30 11 */2 * * someScript3.sh  <-- Takes a long time let's say 36 hours.
* 12 * * * someScript4.sh

Is it smart enough to run the remaining jobs at the appropriate times? For example, the long script doesn't need to terminate?

Also, what happens if the initial long script is still running and it gets called by cron again?

2
  • Cron doesn't care how long the jobs run; it will run additional copies.
    – Jeff Schaller
    Nov 9, 2015 at 22:32
  • Please ensure your questions are formatted properly.
    – Bram
    Nov 9, 2015 at 22:32

4 Answers 4

36

Each cron job is executed independent of any other jobs you may have specified. This means that your long-lived script will not impede other jobs from being executed at the specified time.

If any of your scripts are still executing at their next scheduled cron interval, then another, concurrent, instance of your script will be executed.

This can have unforeseen consequences depending on what your script does. I would recommend reading the Wikipedia article on File Locking, specifically the section on Lock files. A lock file is a simple mechanism to signal that a resource — in your case the someScript3.sh script — is currently 'locked' (i.e. in use) and should not be executed again until the lock file is removed.

Take a look at the answers to the following question for details of ways to implement a lock file in your script:

8

Not sure what you mean by appropriate time. Cron will start jobs at the time it scheduled to do so. It does not check other scheduled jobs nor other instances of a job.

So whatever valid jobs you define will be started at the time defined. Any job that runs longer than the defined interval will be started multiple times. It is the responsibility of whoever wrote the job to prevent it from actually running multiple times if that is required. By e.g. checking a lock file or PID file or something.

There are obvious limitations to the amount of processes that can run in parallel but those are not cron specific.

6

In addition to other answers, especially the link posted by @soulcake: If you schedule a long running command with a too short interval, cron will happily execute the second before the first one completes (unless there's some kind of mutex implemented in the command).

That often slows down the original command even further, leading to another instance being run before the previous ones complete, etc. Or it might be undesirable for other reasons.

General way to prevent is to condition running the command with a guard that ensures that a previous command is not running. For example:

10 * * * * pgrep my_slow_command >/dev/null || /usr/local/bin/my_slow_command

Make sure that pgrep matches the command's name when it runs, e.g. python scripts have python as the name of the executable, which is probably not specific enough and you would have to match against the python's script name as well.

10 * * * * pgrep -f my_script.py || /usr/local/bin/my_script.py

(pgrep without '-f' option matches bash script names, though)

If you can't use pgrep for some reason:

10 * * * * ps ax | grep [m]y_command || /usr/local/bin/my_command

The brackets are used to avoid matching the grep command itself.

0

I use flock.

* * * * * exec flock --nonblock .ws_client.lock -c ws_client.py >& /tmp/ws_client.out

You must log in to answer this question.

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