在OpenShift(红帽云)上每5分钟运行一次CRON作业

在OpenShift(红帽云)上每5分钟运行一次CRON作业,cron,openshift,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分钟运行一次此脚本。在OpenShift上运行CRON作业的唯一方法似乎是使用他们的CRON插件。CRON插件只允许每分钟、每小时和每日脚本(通过将脚本放在相应的文件夹中)

我正在尝试每5分钟运行一次此脚本:

#!/bin/bash
php /var/lib/openshift/53434c795973ca1ddc000668/app-root/runtime/repo/scheduled.php > /dev/null 2>&1
但现在它每分钟运行一次(因为它被放在minutely文件夹中)


如何重新编写脚本,使其每5分钟运行一次?

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

大概是这样的:

#!/bin/bash

minute=$(date +%M)
if [[ $minute =~ [05]$ ]]; then
    php ...
fi
=~
运算符的右操作数是正则表达式;如果当前分钟以
0
5
结束,则上述匹配。其他几种方法也是可能的:

if [[ $minute =~ .[05] ]]; then
(检查是否有任何字符后跟
0
5
$minute
始终正好是2个字符)

(用户theshadowmonkey在评论中建议:

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

它从算术上检查
$minute
是否是5的倍数,但有一个问题表达式,带前导零的常数被视为八进制;如果当前是小时后8或9分钟,常数
08
09
是一个错误。您可以使用
sed
解决这个问题,但考虑到还有其他解决方案,这可能不值得。)

我将扩展Keith Thompson的答案:

他的解决方案每5分钟就可以很好地工作,但如果说每13分钟就不行了;如果我们使用
$minutes%13
我们可以得到以下时间表:

5:13
5:26
5:30
5:52
6:00 because 0%13 is 0
6:13
...
我相信你注意到了这个问题。如果我们计算分钟(、小时、天或周),我们可以实现任何频率,因为:

返回当前日期,我们将其格式化为自历元起的秒(
%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}/
文件夹作为您的频率。

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

下面是每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_作业”将被执行,现在它尝试查找在过去4分钟内修改的文件“last_run”。但是你的 文件“last_run”是在一分钟前创建的,因此条件失败并退出。这种情况还在继续
  • 在第五分钟,当查找(使用
    -mmin+4
    )时,将显示您的“最后一次运行”,现在,将删除并重新创建文件“最后一次运行”,并执行您的awesome命令

来源(官方文件):

上述答案错误,从第50-59分钟开始每分钟执行一次。因此,将条件更改为“if[$($minute%5))-eq 0];然后”就可以了。由于某种原因,我的编辑被拒绝了。所以,我只想在评论中留下正确的答案。作者或其他人可以使用此语句编辑答案。@theshadowmonkey:完成。谢谢你接电话。我已经包括了几个备选方案(这可能有些过分)。@theshadowmonkey在使用if[$($minute%5))-eq 0]时;然后我得到错误:08:value对base太大(错误标记为“08”)@KeithThompson修复Shadowmonkey的示例:“如果[$((10#$minute%5))-eq 0];那么“@NicholasVasilaki:捕捉得好!我已经更新了我的答案。
#!/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