Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run CRON job every 5 minutes on OpenShift (Red Hat Cloud)

Tags:

cron

openshift

I'm trying to run this script every 5 minutes. It seems the only way to run CRON jobs on OpenShift is to use their CRON plugin. And the CRON plugin only allows for minutely, hourly, and daily scripts (by placing the script in the corresponding folder).

I am trying to run this script every 5 minutes:

#!/bin/bash
php /var/lib/openshift/53434c795973ca1ddc000668/app-root/runtime/repo/scheduled.php > /dev/null 2>&1

But right now it runs every minute (because it's placed in the minutely folder).

How can I re-write it so that it runs every 5 minutes?

like image 360
Eric Posen Avatar asked Apr 14 '14 22:04

Eric Posen


People also ask

How do I schedule a cron job every 5 minutes?

basic 3. /usr/bin/vim. tiny 4. /bin/ed Choose 1-4 [1]: Make a new line at the bottom of this file and insert the following code. Of course, replace our example script with the command or script you wish to execute, but keep the */5 * * * * part as that is what tells cron to execute our job every 5 minutes.

How do I run a cron job in OpenShift?

You create a cron job in OpenShift Container Platform by creating a job object. Schedule for the job specified in cron format. In this example, the job will run every minute. An optional concurrency policy, specifying how to treat concurrent jobs within a cron job.

How do I run a cron job every 10 minutes?

For example, 0-23/2 can be used in the hours field to specify command execution every other hour. Steps are also permitted after an asterisk, so if you want to say every two hours just use */2. In this example, */10 in the minutes field to specify command execution every 10 minute.

How do I run a cron job automatically?

Cron job syntaxcrontab -e : edits crontab entries to add, delete, or edit cron jobs. crontab -l : list all the cron jobs for the current user. crontab -u username -l : list another user's crons. crontab -u username -e : edit another user's crons.


2 Answers

Modify the script so it checks the current time, and bails out if it's not a multiple of 5 minutes.

Something like this:

#!/bin/bash

minute=$(date +%M)
if [[ $minute =~ [05]$ ]]; then
    php ...
fi

The right operand of the =~ operator is a regular expression; the above matches if the current minute ends in 0 or 5. Several other approaches are possible:

if [[ $minute =~ .[05] ]]; then

(check for any character followed by a 0 or 5; $minute is always exactly 2 characters).

(User theshadowmonkey suggests in a comment:

if [ $(($minute % 5)) -eq 0 ]; then

which checks arithmetically whether $minute is a multiple of 5, but there's a problem with that. In the expression in a $(( ... )) expression, constants with leading zeros are treated as octal; if it's currently 8 or 9 minutes after the hour, the constant 08 or 09 is an error. You could work around this with sed, but it's probably not worthwhile given that there are other solutions.)

like image 78
Keith Thompson Avatar answered Jan 06 '23 03:01

Keith Thompson


I will extend Keith Thompson answer:

His solution works perfectly for every 5 minutes but won't work for, let's say, every 13 minutes; if we use $minutes % 13 we get this schedule:

5:13
5:26
5:30
5:52
6:00 because 0%13 is 0
6:13
...

I'm sure you notice the issue. We can achieve any frequency if we count the minutes(, hours, days, or weeks) since Epoch:

#!/bin/bash

minutesSinceEpoch=$(($(date +'%s / 60')))

if [[ $(($minutesSinceEpoch % 13)) -eq 0 ]]; then
    php [...]
fi

date(1) returns current date, we format it as seconds since Epoch (%s) and then we do basic maths:

# .---------------------- bash command substitution
# |.--------------------- bash arithmetic expansion
# || .------------------- bash command substitution
# || |  .---------------- date command
# || |  |   .------------ FORMAT argument
# || |  |   |      .----- formula to calculate minutes/hours/days/etc is included into the format string passed to date command
# || |  |   |      |
# ** *  *   *      * 
  $(($(date +'%s / 60')))
# * *  ---------------
# | |        | 
# | |        ·----------- date should result in something like "1438390397 / 60"
# | ·-------------------- it gets evaluated as an expression. (the maths)
# ·---------------------- and we can store it

And you may use this approach with hourly, daily, or monthly cron jobs on OpenShift:

#!/bin/bash
# We can get the

minutes=$(($(date +'%s / 60')))
hours=$(($(date +'%s / 60 / 60')))
days=$(($(date +'%s / 60 / 60 / 24')))
weeks=$(($(date +'%s / 60 / 60 / 24 / 7')))

# or even

moons=$(($(date +'%s / 60 / 60 / 24 / 656')))

# passed since Epoch and define a frequency
# let's say, every 7 hours

if [[ $(($hours % 7)) -ne 0 ]]; then
    exit 0
fi

# and your actual script starts here

Notice that I used the -ne (not equal) operator to exit the script instead of using the -eq (equal) operator to wrap the script into the IF construction; I find it handy.

And remember to use the proper .openshift/cron/{minutely,hourly,daily,weekly,monthly}/ folder for your frequency.

like image 20
stefanmaric Avatar answered Jan 06 '23 02:01

stefanmaric