在OpenShift上每5分钟运行一次CRON作业(Red Hat Cloud)

时间:2014-04-14 22:36:43

标签: cron openshift

我试图每5分钟运行一次这个脚本。似乎在OpenShift上运行CRON作业的唯一方法是使用他们的CRON插件。 CRON插件只允许每分钟,每小时和每日脚本(通过将脚本放在相应的文件夹中)。

我试图每5分钟运行一次这个脚本:

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

但是现在它每分钟运行一次(因为它放在每分钟文件夹中)。

如何重新编写它以便每5分钟运行一次?

3 个答案:

答案 0 :(得分:10)

修改脚本以便检查当前时间,如果它不是5分钟的倍数则退出。

这样的事情:

#!/bin/bash

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

=~运算符的右操作数是正则表达式;如果当前分钟以05结尾,则上述匹配。其他几种方法也是可能的:

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

(检查后跟05的任何字符; $minute总是正好是2个字符。)

(用户theshadowmonkey在评论中建议:

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

从算术上检查$minute是否是5的倍数,但是这有问题。在$(( ... ))表达式中的表达式中,带有前导零的常量被视为八进制;如果它在当前时间后8或9分钟,则常量0809是错误的。您可以使用sed解决此问题,但鉴于还有其他解决方案,这可能不值得。)

答案 1 :(得分:8)

我将延伸基思汤普森的回答:

他的解决方案每隔5分钟就能完美运行,但是,每隔13分钟,我们就会努力工作。如果我们使用$minutes % 13,我们就会得到这个时间表:

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

我确定你注意到了这个问题。如果我们计算自Epoch以来的分钟数(小时,天或周),我们就可以达到任何频率:

#!/bin/bash

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

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

date(1)返回当前日期,我们将其格式化为自Epoch(%s)以来的秒数,然后我们进行基本数学运算:

# .---------------------- 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

你可以在OpenShift上使用这种方法来完成每小时,每天或每月的cron工作:

#!/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

请注意,我使用-ne(不等于)运算符退出脚本,而不是使用-eq(等于)运算符将脚本包装到IF构造中;我发现它很方便。

请记住为频率使用正确的.openshift/cron/{minutely,hourly,daily,weekly,monthly}/文件夹。

答案 2 :(得分:0)

您可以使用详细 cron作业。作业以指定的频率运行,您可以检查作业以检查作业运行的日期和/或时间。

以下是每5分钟运行一次作业的示例。将以下代码段放在路径.openshift/cron/minutely/awesome_job的可执行文件中,并提供适当的权限chmod +x awesome_job,然后将其添加到您的应用程序存储库,提交并推送。

摘录

#!/bin/bash
if [ ! -f $OPENSHIFT_DATA_DIR/last_run ]; then
  touch $OPENSHIFT_DATA_DIR/last_run
fi
if [[ $(find $OPENSHIFT_DATA_DIR/last_run -mmin +4) ]]; then #run every 5 mins
  rm -f $OPENSHIFT_DATA_DIR/last_run
  touch $OPENSHIFT_DATA_DIR/last_run
  # The 'awesome_command(s)' that you want to run every 5 minutes
fi

<强>解释

  • 这段代码实际上创建了一个名为'last_run'的空文件 记下最后一次运行状态,然后开始工作。
  • 下一分钟,您的'awesome_job'将被执行,现在它会尝试查找最近4分钟内修改过的'last_run'文件。但是你的 文件'last_run'是在一分钟前创建的,因此条件失败并退出。这种情况还在继续。
  • 在第五分钟,在找到(使用-mmin +4)时,将显示“last_run”,现在,文件“last_run”将被删除并重新创建,并且您的精彩命令将被执行。

来源(官方文件):https://developers.openshift.com/managing-your-applications/background-jobs.html#_execution_timing