如何每 X 分钟运行一次 cronjob?

Posted

技术标签:

【中文标题】如何每 X 分钟运行一次 cronjob?【英文标题】:How to run a cronjob every X minutes? 【发布时间】:2014-11-02 15:15:30 【问题描述】:

我在 cronjob 中运行 php 脚本,我想每 5 分钟发送一次电子邮件

我当前的(crontab)cronjob:

10 * * * * /usr/bin/php /mydomain.in/cromail.php > /dev/null 2>&1

cronmail.php如下:

<?php
$from = 'D'; // sender
$subject = 'S';
$message = 'M';
$message = wordwrap($message, 70);
mail("myemail@gmail.com", $subject, $message, "From: $from\n");
?>

但是我在 30 分钟内没有收到使用此配置的电子邮件。

【问题讨论】:

你的绝对路径可能不正确 请建议我正确的路径,我的 php 文件 cromail.php 进入根目录 - mydomain.in/cromail.php 有时 php-cli 不想工作只是因为您没有在 php.ini 中设置当前时区,即使您不使用日期也是如此。 cromail.php 还是cronmail.php cromail.php 仅用于测试 【参考方案1】:

crontab 文件中,字段为:

一小时的分钟。 一天中的小时。 一个月中的哪一天。 一年中的月份。 星期几。

所以:

10 * * * * blah

表示在每小时过 10 分钟执行blah

如果您希望每五分钟一次,请使用以下任一方式:

*/5 * * * * blah

意思是每分钟,但只有每五分之一,或者:

0,5,10,15,20,25,30,35,40,45,50,55 * * * * blah

适用于不理解 */x 表示法的旧 cron 可执行文件。

如果它仍然在那之后似乎不起作用,请将命令更改为:

date >>/tmp/debug_cron_pax.txt

并监控该文件以确保每五分钟写入一次内容。如果是这样,那么您的 PHP 脚本有问题。如果不是,那么您的 cron 守护程序有问题。

【讨论】:

我更新 */5 * * * * mydomain.in/cronmail.php > /dev/null 2>&1 没有收到邮件 我也使用了这里提到的命令,但它不起作用,因为它后面有一个 return 语句。确保不要以 return 和注释结束语句,当创建新的 cron 时,它会显示“crontab:正在安装新的 crontab”消息。【参考方案2】:

您的 CRON 应如下所示:

*/5 * * * *

CronWTF 在您需要测试 CRON 设置时非常有用。

将输出通过管道传输到日志文件中可能是个好主意,这样您就可以查看脚本是否也抛出任何错误 - 因为您不会在终端中看到它们。

还可以尝试在 PHP 文件的顶部使用 shebang,以便系统知道在哪里可以找到 PHP。如:

#!/usr/bin/php

这样你就可以这样称呼整个事情

*/5 * * * * php /path/to/script.php &gt; /path/to/logfile.log

【讨论】:

我更新 */5 * * * * mydomain.in/cronmail.php > /dev/null 2>&1 没有收到邮件 您是否尝试过手动运行脚本而不是通过 cron?问题实际上可能出在脚本本身。 FYI 未来的旅行者 - CronWTF 似乎永久关闭。试图编辑原件但不能。【参考方案3】:

您将 cron 设置为每小时第 10 分钟运行。 要将其设置为every 5 mins,请更改为*/5 * * * * /usr/bin/php /mydomain.in/cronmail.php &gt; /dev/null 2&gt;&amp;1

【讨论】:

我更新 */5 * * * * mydomain.in/cronmail.php > /dev/null 2>&1 没有收到邮件 @user3705511 您忘记通过 php 运行它 - 缺少 usr/bin/php 部分 已添加 */5 * * * * usr/bin/php/mydomain.in/cronmail.php > /dev/null 2>&1 但仍收不到邮件 @user3705511 */5 * * * * /usr/bin/php /mydomain.in/cromail.php &gt; /dev/null 2&gt;&amp;1 已更新但仍未收到电子邮件 */5 * * * * usr/bin/php/mydomain.in/cronmail.php > /dev/null 2>&1【参考方案4】:

如果您想每 n 分钟运行一次 cron,则有几个可能的选项取决于 n 的值。

n 除以 60(1、2、3、4、5、6、10、12、15、20、30)

在这里,通过使用/ 表示法,解决方案很简单:

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
# *  *  *  *  *   command to be executed
m-59/n  *  *  *  *   command

在上面,n 表示值nm 表示小于n* 的值。这将在分钟m,m+n,m+2n,... 执行命令

n 不整除 60

如果n 不除60,你不能用cron 干净地做到这一点,但这是可能的。为此,您需要在测试检查时间的 cron 中进行测试。这最好在查看 UNIX 时间戳时完成,即自 1970-01-01 00:00:00 UTC 以来的总秒数。假设我们想在 Marty McFly 到达 Riverdale 时第一次开始运行该命令,然后每隔 n 分钟后重复一次。

% date -d '2015-10-21 07:28:00' +%s 
1445412480

对于在 `2015-10-21 07:28:00' 之后每 42nd 分钟运行一次 cronjob,crontab 将如下所示:

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
# *  *  *  *  *   command to be executed
  *  *  *  *  *   minutetestcmd "2015-10-21 07:28:00" 42 && command

minutetestcmd 定义为

#!/usr/bin/env bash
starttime=$(date -d "$1" "+%s")
# return UTC time
now=$(date "+%s")
# get the amount of minutes (using integer division to avoid lag)
minutes=$(( (now - starttime) / 60 ))
# set the modulo
modulo=$2
# do the test
(( now >= starttime )) && (( minutes % modulo == 0 ))

备注:UNIX时间不受闰秒影响

备注:cron没有亚秒级精度

【讨论】:

m/n 符号似乎不适用于我的系统(Debian 9、Ubuntu 16.04)。只有*/n 有效。例如,5/54/10 在 syslog 中给出 Error: bad minute; while reading /etc/crontab(在 Ubuntu 中使用 cron v. 3.0pl1-128ubuntu2)。这种 m/n 符号是否已被放弃,还是仅在某些系统中可用? @mivk 感谢您指出这一点。这是我这边的一个错误。它应该是m-59/n。只有一个范围可以有一个步长。 (见man 5 crontab)。我已经更新了答案【参考方案5】:

检查 cronjob 是否正常工作的 2 个步骤:

    使用执行 cronjob 的用户登录服务器

    手动运行php命令:

    /usr/bin/php /mydomain.in/cromail.php

并检查是否显示任何错误

【讨论】:

【参考方案6】:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

要设置 x 分钟,我们需要在第一个参数中设置 x 分钟,然后是脚本的路径

15 分钟

*/15 * * * *  /usr/bin/php /mydomain.in/cromail.php > /dev/null 2>&1

【讨论】:

这不会每 x (15) 分钟运行一次任务。它会在每整整一小时后的 x (1) 分钟运行一次。

以上是关于如何每 X 分钟运行一次 cronjob?的主要内容,如果未能解决你的问题,请参考以下文章

每分钟运行一次 cronjob 的风险

每分钟运行一次cronjob的风险

每分钟运行一次 PHP 脚本

每分钟 Cronjob

Crontab 每 15 分钟运行一次,除了凌晨 3 点?

每 5 分钟运行一次 Cron 作业,持续 10 秒