How to make sure one cronjob is run after another cronjob is completed? - cron

I need to run two cronjobs. One is to run in every 20 minutes every day from 1AM to midnight. Then the second job is scheduled to run at midnight.
*/20 1-23 * * * root [job1]
0 0 * * * root [joob2]
However, I need to make sure that job 2 is completed when job 1 is run again.
How can I do this?

I think this is what you might be after
*/20 1-23 * * * root while [ ! -e $HOME/jobmarker ]; do sleep 5; done && command_job1
0 0 * * * root rm $HOME/jobmarker && command_job2 && touch $HOME/jobmarker
This will only run job1 if the file $HOME/jobmarker exists. If not, it will wait until it is generated.
The second job will first remove the marker, run the command and then set the marker again.

A simple solution is to make job 2 create a flag file (eg touch) when starting, which it will remove when it's completed.
Then job11 should check if the file exists and make it exit / don't run if it exists. Or sleep for a specified amount of time and then try again.

Related

How to set crontab every 1 hour 1 minute

I want to schedule a command every 1 hour and 1 minute. For example, if the first command executes at 01:01 pm, the next command will execute at 01:02PM; the time between the command executions is 1 hour and 1 minute.
I tried using
*/1 */1 * * *
but it runs every minute. Can anyone help me?
There's no way in crontab to schedule a job to run every 61 minutes (which, BTW, is an odd thing to want to do), but you can do it indirectly.
You can schedule a job to run every minute:
* * * * * wrapper_script
where wrapper_script invokes the desired command only if the current minute is a multiple of 61, something like this:
#!/bin/bash
second=$(date +%s)
minute=$((second / 60))
remainder=$((minute % 61))
if [[ $remainder == 0 ]] ; then
your_command
fi
This sets $minute to the number of minutes since the Unix epoch, 1970-01-01 00:00:00 UTC. You can adjust when the command runs by using a value other than 0 in the comparison.
That's assuming you want it to run every 61 minutes (which is what you asked). But if you want to repeat in a daily cycle, so it runs at 00:00, 01:01, ..., 23:23, and then again at 00:00 the next day, you can do it directly in crontab:
0 0 * * * your_command
1 1 * * * your_command
2 2 * * * your_command
# ...
21 21 * * * your_command
22 22 * * * your_command
23 23 * * * your_command
You can use this method which tells it to run every 61 minutes after the cron job.
while true
do
# do stuff here every 61 minutes
sleep 61m
done
Another option:
Cron can easily run every hour, but 61 minutes is harder to achieve.
The normal methods include using a sleep command or various rather
elaborate methods in the script itself to fire off every 61 minutes.
A much simpler method is using cron's cousin, the at command. The at
command will run through a file and run all the commands inside, so
you just need to place the commands in a file, one per line, then add
this line to the bottom of the file:
at now + 61 minutes < file
The commands can be any type of one-liner you want to use.
Here is an example. Call this file foo and to kick off the execution
the first time, you can simply run: sh foo
date >> ~/foo_out
cd ~/tmp && rm *
at now + 61 minutes < ~/foo
That will output the date and time to ~/foo_out then move to a tmp
directory and clean out files, then tell the at command to run itself
again in 61 minutes which will again run the at command after
executing the rest.

How the cron timing is working?

Suppose, current time is 11:42 and i have setup one cron file to run at every 5 minutes.
Then this file will run at which time 11:47 or 11:45?
So basically i am trying to understand that how the cron timing is work?
Edit : it was ran at 11:45, but i don't know the reason behind it
Cron Configuration :
*/5 * * * * wget -O /dev/null http://XXX/index.php?r=controller/action
As you know, cron will run jobs at a specific time.
A cron job will not use the time it was started, only the configuration matters. This means a cron job set to every 5 minutes (like your */5 * * * *) will only ever run at times ending with 0 or 5 (eg: 12:00, 12:05, 12:10), regardless of the time you run it. This makes sense because we want to schedule a job for a specific time.
If you really need a job to run every 5 minutes, with an offset (eg: 11:42, 11:47, 11:52) you will have to give a list in the configuration.
instead of (*/5 * * * *) you would need to use:
(2,7,12,...,57 * * * *), filling ... with all the other numbers.

Can't make crontab work

I am new to Linux and Ubuntu and I seldom have to use it. I am trying to make this PHP script to run every minute using cron, but firstly I wanted to make some tests.
I created an empty file at /var/www/html/ called test. I ran on terminal:
sudo crontab -e
And added this line:
0 * * * * rm /var/www/html/test
Then saved it and exited. It said "Installing new Crontab"
Nothing happened. Then I created a file bfile.sh that contained:
#!/bin/sh
rm /var/www/html/test
and added the following to crontab:
0 * * * * bash /var/www/html/bfile.sh
Still nothing happened.
What do I have to do to see anything happening from crontab? By the way I checked and the service is running
0 * * * * basically says "run this at 0th minute of every hour."
If you need cron to run your command every minute do * * * * *.
0 * * * * runs once every 1 hour. If you want to run every minute it should be */1 * * * *
You can also check the /var/log/cron file for any errors

Cron runs after other cron

I want to set a cron run after an other cron. For example: Cron A finishs at 01:00 PM, cron B will start at 01:01 PM. The problem is I don't know when cron A finishs.
I checked the crontab syntax. It doesn't provide any param for that purpose.
My actual situation is:
# This cron must run first.
? ? * * * /usr/local/bin/php -f /path/select_and_print_to_log_file.php
# two these crons runs at the same time.
0 13 * * * /usr/local/bin/php -f /path/update_user.php
0 13 * * * /usr/local/bin/php -f /path/update_image.php
# This cron runs right after two above cron completes.
? ? * * * /usr/local/bin/php -f /path/select_and_print_to_log_file.php
You can use the batch command inside the first cron to have the second thing being scheduled to run.
Your first job could produce a timestamp when finished.
Then you estimate - for example - that job A needs about 60 to 90 minutes. After 60 minutes, you start job B. Job b looks for the timestamp. If it is present, job B starts, else it waits for a minute and looks again.
After finishing, job B deletes the timestamp, or renames it, maybe from 'todo' to 'done'. You could insert the current date inside the file, to check, whether your estimation is still acceptable, or should be adjusted.
What I do in such cases (commonly a backup scenario where I don't want to thrash the disk by having concurrent backups) is to write a script that cron calls, and in the script have the actual tasks run serially.
Something like:
#!/bin/bash
/usr/local/bin/php -f /path/update_user.php
/usr/local/bin/someOtherTaskToRunSecond
YMMV.

Cron jobs -- to run every 5 seconds

I want to create cron job that runs a script every 5 seconds. Seeing that cron jobs only allows increments of minutes 0-59 and so on.
I thought to create another script that calls my original script written below.
#!/bin/bash
while true
do
# script in the same directory as this script. is this correct?
bash makemehappy.sh
sleep 1
done
I now, need to know how to run this script every time i boot my computer and for it to start itself if it isn't running for some reason.
I am also aware that running this script every minute wouldn't be a good thing. :)
if there is an easier way to run a script every 5 seconds please advise.
Please and thank you.
I wouldn't use cron for this. I would use that bash script (use an absolute path, unless you want it to be portable and know that the directory structure will be preserved).
Instead, I would just sleep 5, just like you did (only 5 seconds instead of 1).
As far as starting it with your system, that depends on the system. On (some) Linux distros, there's a file called /etc/rc.local in which you can add scripts to run when the system starts. Well... I shouldn't be so general, the distros that I have used have this. If you're running Ubuntu, there is no longer an inittab, they use upstart, btw.
So if you have an endless loop and an entry in /etc/rc.local, then you should be golden for it to run endlessly (or until it encounters a problem and exits).
Try using anacron or, better yet, an init script to start when the computer starts.
If you want the script to "restart itself", you'll need to run something every few minutes to check the original is still running. This can be done in inittab (/etc/inittab) or, on Ubuntu, /etc/event.d. Try man 5 inittab, looking at the 'respawn' option.
Some crons have an #reboot time specifier (this covers all the time and date fields). If yours does, you can use that. If this is a "system" service (rather than something running for yourself), the other solutions here are probably better.
Init scripts are fine at boot, but don't detect if a process fails and has to be restarted. supervisord does a great job of detecting failed processes and restarting them. I'd recommend a script with a 5-second loop like #Tim described, but wrap supervisord around it to make sure it keeps running.
As explained in detail in my answer to a similar question, you can use SystemD timer units with whatever schedule that you want - down to a theoretical 1 nanosecond schedule with no sleep kludges
Quick overview:
Setup a SystemD service to run what you want - this can be as simple as:
/home/myusuf3/.config/systemd/user/makemehappy.service
[Unit]
Description=Make me happy
[Service]
ExecStart=/home/myusuf3/.local/bin/makemehappy.sh
Setup a SystemD timer with the schedule that you want, as documented in man systemd.timer:
/home/myusuf3/.config/systemd/user/makemehappy.timer
[Unit]
Description=Schedule to make me happy
[Timer]
OnBootSec=5
OnUnitActiveSec=5
AccuracySec=1
Enable and start the timer:
:
systemctl --user daemon-reload
systemctl --user enable makemehappy.timer
systemctl --user start makemehappy.timer
(after you enable it, it will autostart every time you start the computer, but you probably want to start it now anyway).
To answer the question in the title, this is how to run a cronjob every 5 seconds :
* * * * * /path/to/script.sh
* * * * * sleep 5 && /path/to/script.sh
* * * * * sleep 10 && /path/to/script.sh
* * * * * sleep 15 && /path/to/script.sh
* * * * * sleep 20 && /path/to/script.sh
* * * * * sleep 25 && /path/to/script.sh
* * * * * sleep 30 && /path/to/script.sh
* * * * * sleep 35 && /path/to/script.sh
* * * * * sleep 40 && /path/to/script.sh
* * * * * sleep 45 && /path/to/script.sh
* * * * * sleep 50 && /path/to/script.sh
* * * * * sleep 55 && /path/to/script.sh
It's not beautiful, but this solution comes with no extra tools nor dependencies. So if you have working cron jobs, this should work right away.

Resources