How to schedule multiple CronJobs using bash without conflicting each other? - linux

I have 4 Jobs, which run at different intervals. How can I prevent them from conflicting each other? Job 2,3,4 can only be run one at a time. Any new job invocation must wait for old completion before beginning.
0 9,11,14 * * 1-5 /bin/bash /home/userName/Desktop/Auto/job_1.sh
0 8-17 * * 1-5 /bin/bash /home/userName/Desktop/Auto/job_2.sh
*/6 * * * * /bin/bash /home/userName/Desktop/Auto/job_3.sh
*/20 * * * * /bin/bash /home/userName/Desktop/Auto/job_4.sh
Any help is much appreciated. Thanks!

I would look into using flock.
You have to install util-linux to get flock.
It has lots of options like timeout, etc.
Your crontab could look something like this:
0 9,11,14 * * 1-5 flock -x /tmp/cronjobs.lock -c '/bin/bash /home/userName/Desktop/Auto/job_1.sh'
0 8-17 * * 1-5 flock -x /tmp/cronjobs.lock -c '/bin/bash /home/userName/Desktop/Auto/job_2.sh'
*/6 * * * * flock -x /tmp/cronjobs.lock -c '/bin/bash /home/userName/Desktop/Auto/job_3.sh'
*/20 * * * * flock -x /tmp/cronjobs.lock -c '/bin/bash /home/userName/Desktop/Auto/job_4.sh'
The syntax for flock is:
flock -x <lockfile> -c '<command>'
The lockfile is a file that is locked on your machine. Each new command will check to see if that file is locked by a previous command. Once that previous command finishes, it releases the lock and the next command can run, taking out a new lock.
Using the -w <seconds> command you can tell flock the time in seconds to wait while trying to take out a lock on the file before the command fails and does not run.
For instance, the following would wait 3 minutes for previous cron job to finish. If it did not finish in that time then the command below would not run.
*/20 * * * * flock -w 180 -x /tmp/cronjobs.lock -c '/bin/bash /home/userName/Desktop/Auto/job_4.sh'

Related

Crontab every 5 minutes, but not on 5,10,15, etc

Some of my sites need regular crontabs, I use this to start a cronjob every 5 minutes "*/5 * * * *".
The crontabs are small, light, but there are starting to be several sites that need them, and starting them all together, it starts not being a very good idea.
With this "*/5" the cron starts at 5, 10, 15 20, etc... is it possible to make it start at, for example 8,13,18,23, etc?
Vixie cron accepts steps in a range (thanks Keith Thompson), so you can do
3-58/5 * * * * my_command
With other versions of cron, this may not be supported and you'd just have to do
3,8,13,18,23,28,33,38,43,48,53,58 * * * * my_command
Another option is something like
*/5 * * * * sleep 3m ; my_command
This could be adapted to sleep for a random time, thus further spreading out the jobs. For instance, you could do
*/5 * * * * /bin/bash -c 'sleep $((RANDOM/(32767/180))) ; my_command'
or use SHELL = /bin/bash further up in your crontab to make the /bin/bash -c unnecessary, if you're okay with using bash to run all the other cron jobs following the SHELL = line. $RANDOM in bash expands to a random integer between 0 and 32767, so this gets you a delay of up to 180 seconds.

Cron jobs not running in VestaCP (CentOs)

I have written some PHP scripts that I am trying to run with cron jobs in VestaCP, but they don't seem to be running. I have tried to search for other threads on here and on the VestaCP forum that could help me identify the error, but have not found a solution.
Server system:
CentOs 7.4
Vesta 0.9.8-22
I have tested the PHP scripts by going to the links directly. They all work well. But the cron jobs are not running and I can't figure out why.
I have not been able to locate any error messages or logs generated by these cron jobs (even when I remove the "> /dev/null 2>&1"). But I might have been looking in the wrong places.
All of the cron jobs have been added through the VestaCP cron interface.
I have disabled exim, dovecot, clamd, and spamassassin. And I have turned off notifications in the cron panel. Not sure if that is related.
Copied from /var/spool/cron/admin [edited domain name]:
15 02 * * * sudo /usr/local/vesta/bin/v-update-sys-queue disk
10 00 * * * sudo /usr/local/vesta/bin/v-update-sys-queue traffic
30 03 * * * sudo /usr/local/vesta/bin/v-update-sys-queue webstats
*/5 * * * * sudo /usr/local/vesta/bin/v-update-sys-queue backup
10 05 * * * sudo /usr/local/vesta/bin/v-backup-users
20 00 * * * sudo /usr/local/vesta/bin/v-update-user-stats
*/5 * * * * sudo /usr/local/vesta/bin/v-update-sys-rrd
15 6 * * * sudo /usr/local/vesta/bin/v-update-sys-vesta-all
01 4 * * * sudo /usr/local/vesta/bin/v-update-letsencrypt-ssl
*/5 * * * * wget -q -O - "https://testing.example.com/cli/new-projects" > /dev/null 2>&1
*/5 * * * * wget -q -O - "https://example.com/cli/new-projects" > /dev/null 2>&1
30 10 * * * wget -q -O - "https://example.com/cli/project-expiration" > /dev/null 2>&1
*/5 * * * * sudo /usr/local/vesta/bin/v-update-sys-queue letsencrypt
0 10 * * * wget -q -O - "https://testing.example.com/cli/project-expiration" > /dev/null 2>&1
*/2 * * * * wget -q -O - "https://testing.example.com/cli/email-sender" > /dev/null 2>&1
*/2 * * * * wget -q -O - "https://example.com/cli/email-sender" > /dev/null 2>&1
I had the same problem in Ubuntu.
The problem was that the cron jobs created from VestaCP control panel is created for the user and although there is sudo at the beginning of the command, they are not run.
They seem to be called since I can see them on the /tmp/log/syslog file. It does not show any error though. But for some reason, the commands are not executed.
Here are few simple commands to check cron status.
Check if Cron service is running:
pgrep cron
if a number is returned the service is running else not
Check Cron status:
systemctl status cron
Check the current cron file:
crontab -l
Edit cronjob file:
crontab -e
One solution is to create the cron jobs for the root user from the terminal. I have not tried for other users. The cron jobs created for root user will run without a problem.

Offset Crons with Sleep and Flock together

I run several cron jobs every minute - I use flock to prevent overlapping as a couple of the scripts may run for over minute:
* * * * * flock -n /path/to/lock-process-1.txt php /path/to/process-1.php
* * * * * flock -n /path/to/lock-process-2.txt php /path/to/process-2.php
However, all the processes run at the same time (and most of the processes only take a few seconds). So I'd like to stagger the crons so that they are ten seconds apart. I have read elsewhere that this can be done with sleep (from this post):
* * * * * sleep 10;curl http://www.google.com/
My question is: can I use sleep alongside flock and if so, where do I add the sleep 10;
I went ahead and tested this and it is OK to have sleep before flock:
* * * * * sleep 10; flock -n /path/to/lock-process-2.txt php /path/to/process-2.php

Cron Jobs Run At Same Time

In my cron job file I have two cronjobs defined:
#Yo1 MAILTO="example#domain.com"
*1****wget -O - -q "http://example.com/cron/test1.php">/dev/null 2>&1
#Yo1 MAILTO="example#domain.com"
*15****wget -O - -q "http://example.com/cron/test2.php">/dev/null 2>&1
The PHP files are simple just sending mails with different subjects.
The issue is that both cronjobs are running on the same time every minute, but as you can see I want them to run on different times. First - every minute, second - every 15 minutes.
Can you help me with this. I can't figure out whats wrong.
Your syntax is incorrect.
Please use the following code
#every minute
* * * * * wget -O - -q "http://example.com/cron/test1.php">/dev/null 2>&1
#every 15 minutes
*/15 * * * * wget -O - -q "http://example.com/cron/test2.php">/dev/null 2>&1
You can use online crontab generators like http://www.crontab-generator.org/
* * * * * wget -O - -q "http://example.com/cron/test1.php">/dev/null 2>&1
15 * * * * wget -O - -q "http://example.com/cron/test2.php">/dev/null 2>&1

CentOS Unix Cron order of execution when all set to same time

I have a series of cron jobs running at the command line calling the php interpreter all by the same user configured to run once a day
0 0 * * * /usr/bin/php -q /mydirectory/myphp.php
0 0 * * * /usr/bin/php -q /mydirectory/myphp2.php
0 0 * * * /usr/bin/php -q /mydirectory/myphp3.php
Do these all execute at once or do the execute in the order of entry in some cron table, complete and move on to the next cron job?
And to answer your question despite the off-topic:
They will get executed in parallel, not sequentially. If you need some order it would pay to add them all to one script, and execute them sequentially separated by &&, e.g.
#!/bin/bash
/usr/bin/php -q /mydirectory/myphp.php && /usr/bin/php -q /mydirectory/myphp2.php && /usr/bin/php -q /mydirectory/myphp3.php

Resources