CRON 作业在该月的最后一天运行

发布于 2024-11-10 01:06:27 字数 75 浏览 5 评论 0原文

我需要创建一个将在每个月的最后一天运行的 CRON 作业。 我将使用 cPanel 创建它。

任何帮助表示赞赏。 谢谢

I need to create a CRON job that will run on the last day of every month.
I will create it using cPanel.

Any help is appreciated.
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(22

终难遇 2024-11-17 01:06:27

也许最简单的方法是简单地执行三项单独的工作:

55 23 30 4,6,9,11        * myjob.sh
55 23 31 1,3,5,7,8,10,12 * myjob.sh
55 23 28 2               * myjob.sh

不过,即使在闰年,这也会在 2 月 28 日运行,因此,如果这是一个问题,您将需要找到另一种方法。


然而,在每个月的第一天尽快运行作业通常会更容易、更正确,例如:

0 0 1 * * myjob.sh

并修改脚本来处理上一个作业> 月数据。

这消除了您在确定哪一天是该月最后一天时可能遇到的任何麻烦,并且还确保该月的所有数据都可用(假设您正在处理数据)。在该月的最后一天到午夜前五分钟跑步可能会让您错过从那时到午夜之间发生的任何事情。

无论如何,对于大多数月末工作来说,这是通常的做法。


如果您仍然确实想要在该月的最后一天运行它,一个选择是简单地检测明天是否是第一个(作为脚本的一部分,或者在 crontab 本身中)。

因此,

55 23 28-31 * * [[ "$(date --date=tomorrow +\%d)" == "01" ]] && myjob.sh

假设您有一个相对智能的 date 程序,那么: 应该是一个好的开始。

如果您的 date 程序不够先进,无法为您提供相对日期,您可以编写一个非常简单的程序来为您提供该月的明天(您不需要 date的全部功能),例如:

#include <stdio.h>
#include <time.h>

int main (void) {
    // Get today, somewhere around midday (no DST issues).

    time_t noonish = time (0);
    struct tm *localtm = localtime (&noonish);
    localtm->tm_hour = 12;

    // Add one day (86,400 seconds).

    noonish = mktime (localtm) + 86400;
    localtm = localtime (&noonish);

    // Output just day of month.

    printf ("%d\n", localtm->tm_mday);

    return 0;
}

然后使用(假设您将其称为 tomdom 表示“明天的某一天”):

55 23 28-31 * * [[ "$(tomdom)" == "1" ]] && myjob.sh

尽管您可能想要考虑添加错误检查,因为两者如果出现问题,time()mktime() 可能会返回 -1。为了简单起见,上面的代码没有考虑到这一点。

Possibly the easiest way is to simply do three separate jobs:

55 23 30 4,6,9,11        * myjob.sh
55 23 31 1,3,5,7,8,10,12 * myjob.sh
55 23 28 2               * myjob.sh

That will run on the 28th of February though, even on leap years so, if that's a problem, you'll need to find another way.


However, it's usually both substantially easier and correct to run the job as soon as possible on the first day of each month, with something like:

0 0 1 * * myjob.sh

and modify the script to process the previous month's data.

This removes any hassles you may encounter with figuring out which day is the last of the month, and also ensures that all data for that month is available, assuming you're processing data. Running at five minutes to midnight on the last day of the month may see you missing anything that happens between then and midnight.

This is the usual way to do it anyway, for most end-of-month jobs.


If you still really want to run it on the last day of the month, one option is to simply detect if tomorrow is the first (either as part of your script, or in the crontab itself).

So, something like:

55 23 28-31 * * [[ "$(date --date=tomorrow +\%d)" == "01" ]] && myjob.sh

should be a good start, assuming you have a relatively intelligent date program.

If your date program isn't quite advanced enough to give you relative dates, you can just put together a very simple program to give you tomorrow's day of the month (you don't need the full power of date), such as:

#include <stdio.h>
#include <time.h>

int main (void) {
    // Get today, somewhere around midday (no DST issues).

    time_t noonish = time (0);
    struct tm *localtm = localtime (&noonish);
    localtm->tm_hour = 12;

    // Add one day (86,400 seconds).

    noonish = mktime (localtm) + 86400;
    localtm = localtime (&noonish);

    // Output just day of month.

    printf ("%d\n", localtm->tm_mday);

    return 0;
}

and then use (assuming you've called it tomdom for "tomorrow's day of month"):

55 23 28-31 * * [[ "$(tomdom)" == "1" ]] && myjob.sh

Though you may want to consider adding error checking since both time() and mktime() can return -1 if something goes wrong. The code above, for reasons of simplicity, does not take that into account.

美男兮 2024-11-17 01:06:27

有一种稍微简短的方法,可以使用类似于上面的方法之一。也就是说:

[ $(date -d +1day +%d) -eq 1 ] && echo "last day of month"

另外,crontab 条目可以更新为仅在 28 日到 31 日检查,因为在该月的其他日子运行它是没有意义的。这会给你:

0 23 28-31 * * [ $(date -d +1day +%d) -eq 1 ] && myscript.sh

There's a slightly shorter method that can be used similar to one of the ones above. That is:

[ $(date -d +1day +%d) -eq 1 ] && echo "last day of month"

Also, the crontab entry could be update to only check on the 28th to 31st as it's pointless running it the other days of the month. Which would give you:

0 23 28-31 * * [ $(date -d +1day +%d) -eq 1 ] && myscript.sh
熊抱啵儿 2024-11-17 01:06:27

对于 AWS Cloudwatch cron 实施(调度 Lambda 等),此方法有效:

55 23 L * ? *

每月最后一天晚上 11:55 运行。

For AWS Cloudwatch cron implementation (Scheduling Lambdas, etc..) this works:

55 23 L * ? *

Running at 11:55pm on the last day of each month.

唱一曲作罢 2024-11-17 01:06:27

继维基百科之后,这个怎么样?

55 23 L * * /full/path/to/command

What about this one, after Wikipedia?

55 23 L * * /full/path/to/command
旧情勿念 2024-11-17 01:06:27

采用 paxdiablo 的解决方案,我在 2 月 28 日和 29 日运行。 29 日的数据覆盖 28 日的数据。

# min  hr  date     month          dow
  55   23  31     1,3,5,7,8,10,12   * /path/monthly_copy_data.sh
  55   23  30     4,6,9,11          * /path/monthly_copy_data.sh
  55   23  28,29  2                 * /path/monthly_copy_data.sh

Adapting paxdiablo's solution, I run on the 28th and 29th of February. The data from the 29th overwrites the 28th.

# min  hr  date     month          dow
  55   23  31     1,3,5,7,8,10,12   * /path/monthly_copy_data.sh
  55   23  30     4,6,9,11          * /path/monthly_copy_data.sh
  55   23  28,29  2                 * /path/monthly_copy_data.sh
一张白纸 2024-11-17 01:06:27

一些 cron 实现支持“L”标志来表示该月的最后一天。

如果您很幸运能够使用其中一个实现,那么它就像这样简单:

0 55 23 L * ?

它将在每月最后一天晚上 11:55 运行。

http://www.quartz-scheduler.org/documentation/quartz -1.x/tutorials/crontrigger

Some cron implementations support the "L" flag to represent the last day of the month.

If you're lucky to be using one of those implementations, it's as simple as:

0 55 23 L * ?

That will run at 11:55 pm on the last day of every month.

http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

帥小哥 2024-11-17 01:06:27

我从这个网站<找到了解决方案(在该月的最后一天),如下所示/a>.

 0 0 0 L * ? *

CRON 详细信息:

Seconds Minutes Hours   Day Of Month    Month   Day Of Week  Year
0       0       0       L               *       ?            *

要交叉验证上述表达式,单击此处,它会提供如下所示的输出。

2021-12-31 Fri 00:00:00
2022-01-31 Mon 00:00:00
2022-02-28 Mon 00:00:00
2022-03-31 Thu 00:00:00
2022-04-30 Sat 00:00:00

I found out solution (On the last day of the month) like below from this site.

 0 0 0 L * ? *

CRON details:

Seconds Minutes Hours   Day Of Month    Month   Day Of Week  Year
0       0       0       L               *       ?            *

To cross verify above expression, click here which gives output like below.

2021-12-31 Fri 00:00:00
2022-01-31 Mon 00:00:00
2022-02-28 Mon 00:00:00
2022-03-31 Thu 00:00:00
2022-04-30 Sat 00:00:00
人生百味 2024-11-17 01:06:27

对于基于 @Indie 解决方案的 crontab 中更安全的方法(使用 date + $() 的绝对路径不适用于所有 crontab 系统):

0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh

For a safer method in a crontab based on @Indie solution (use absolute path to date + $() does not works on all crontab systems):

0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh
兔小萌 2024-11-17 01:06:27

您可以设置一个 cron 作业在每月的每一天运行,并让它运行如下所示的 shell 脚本。该脚本计算明天的天数是否小于今天的天数(即明天是否是新的一个月),然后执行您想要的操作。

TODAY=`date +%d`
TOMORROW=`date +%d -d "1 day"`

# See if tomorrow's day is less than today's
if [ $TOMORROW -lt $TODAY ]; then
echo "This is the last day of the month"
# Do stuff...
fi

You could set up a cron job to run on every day of the month, and have it run a shell script like the following. This script works out whether tomorrow's day number is less than today's (i.e. if tomorrow is a new month), and then does whatever you want.

TODAY=`date +%d`
TOMORROW=`date +%d -d "1 day"`

# See if tomorrow's day is less than today's
if [ $TOMORROW -lt $TODAY ]; then
echo "This is the last day of the month"
# Do stuff...
fi
橙幽之幻 2024-11-17 01:06:27
#########################################################
# Memory Aid 
# environment    HOME=$HOME SHELL=$SHELL LOGNAME=$LOGNAME PATH=$PATH
#########################################################
#
# string         meaning
# ------         -------
# @reboot        Run once, at startup.
# @yearly        Run once a year, "0 0 1 1 *".
# @annually      (same as @yearly)
# @monthly       Run once a month, "0 0 1 * *".
# @weekly        Run once a week, "0 0 * * 0".
# @daily         Run once a day, "0 0 * * *".
# @midnight      (same as @daily)
# @hourly        Run once an hour, "0 * * * *".
#mm     hh      Mday    Mon     Dow     CMD # minute, hour, month-day month DayofW CMD
#........................................Minute of the hour
#|      .................................Hour in the day (0..23)
#|      |       .........................Day of month, 1..31 (mon,tue,wed)
#|      |       |       .................Month (1.12) Jan, Feb.. Dec
#|      |       |       |        ........day of the week 0-6  7==0
#|      |       |       |        |      |command to be executed
#V      V       V       V        V      V
*       *       28-31   *       *       [ `date -d +'1 day' +\%d` -eq 1 ] && echo "Tomorrow is the first today now is  `date`" >> ~/message
1       0       1       *       *       rm -f ~/message
*       *       28-31   *       *       [ `date -d +'1 day' +\%d` -eq 1 ] && echo "HOME=$HOME LOGNAME=$LOGNAME SHELL = $SHELL PATH=$PATH" 
#########################################################
# Memory Aid 
# environment    HOME=$HOME SHELL=$SHELL LOGNAME=$LOGNAME PATH=$PATH
#########################################################
#
# string         meaning
# ------         -------
# @reboot        Run once, at startup.
# @yearly        Run once a year, "0 0 1 1 *".
# @annually      (same as @yearly)
# @monthly       Run once a month, "0 0 1 * *".
# @weekly        Run once a week, "0 0 * * 0".
# @daily         Run once a day, "0 0 * * *".
# @midnight      (same as @daily)
# @hourly        Run once an hour, "0 * * * *".
#mm     hh      Mday    Mon     Dow     CMD # minute, hour, month-day month DayofW CMD
#........................................Minute of the hour
#|      .................................Hour in the day (0..23)
#|      |       .........................Day of month, 1..31 (mon,tue,wed)
#|      |       |       .................Month (1.12) Jan, Feb.. Dec
#|      |       |       |        ........day of the week 0-6  7==0
#|      |       |       |        |      |command to be executed
#V      V       V       V        V      V
*       *       28-31   *       *       [ `date -d +'1 day' +\%d` -eq 1 ] && echo "Tomorrow is the first today now is  `date`" >> ~/message
1       0       1       *       *       rm -f ~/message
*       *       28-31   *       *       [ `date -d +'1 day' +\%d` -eq 1 ] && echo "HOME=$HOME LOGNAME=$LOGNAME SHELL = $SHELL PATH=$PATH" 
倾其所爱 2024-11-17 01:06:27
00 23 * * * [[ $(date +'%d') -eq $(cal | awk '!/^$/{ print $NF }' | tail -1) ]] && job

查看 相关问题 在 unix.com 论坛上。

00 23 * * * [[ $(date +'%d') -eq $(cal | awk '!/^$/{ print $NF }' | tail -1) ]] && job

Check out a related question on the unix.com forum.

海拔太高太耀眼 2024-11-17 01:06:27

设置一个 cron 作业在每月的第一天运行。然后将系统时钟更改为提前一天。

Set up a cron job to run on the first day of the month. Then change the system's clock to be one day ahead.

看春风乍起 2024-11-17 01:06:27

您可以将所有答案连接到一个 cron 行中,并仅使用 date 命令。

只需检查今天和明天的月份日期之间的差异:

0 23 * * * root [ $(expr $(date +\%d -d '1 days') - $(date +\%d)  ) -le 0 ]  && echo true

如果这些差异低于 0,则意味着我们更改了月份并且存在该月的最后一天。

You can just connect all answers in one cron line and use only date command.

Just check the difference between day of the month which is today and will be tomorrow:

0 23 * * * root [ $(expr $(date +\%d -d '1 days') - $(date +\%d)  ) -le 0 ]  && echo true

If these difference is below 0 it means that we change the month and there is last day of the month.

只是一片海 2024-11-17 01:06:27
55 23 28-31 * * echo "[ $(date -d +1day +%d) -eq 1 ] && my.sh" | /bin/bash 
55 23 28-31 * * echo "[ $(date -d +1day +%d) -eq 1 ] && my.sh" | /bin/bash 
弃爱 2024-11-17 01:06:27

在像 Jenkins 这样的工具中,通常不支持 L 也不支持类似于 date 的工具,一个很酷的技巧可能是正确设置时区。例如,Pacific/Kiritimati 的时间为 GMT+14:00,因此如果您在欧洲或美国,这可能会起作用。

TZ=Pacific/Kiritimati \n H 0 1 * * 

结果:最后一次运行时间为 2022 年 4 月 30 日星期六上午 10:54:53 GMT;下次运行时间为 2022 年 5 月 31 日星期二上午 10:54:53 GMT。

In tools like Jenkins, where usually there is no support for L nor tools similar to date, a cool trick might be setting up the timezone correctly. E.g. Pacific/Kiritimati is GMT+14:00, so if you're in Europe or in the US, this might do the trick.

TZ=Pacific/Kiritimati \n H 0 1 * * 

Result: Would last have run at Saturday, April 30, 2022 10:54:53 AM GMT; would next run at Tuesday, May 31, 2022 10:54:53 AM GMT.

ヤ经典坏疍 2024-11-17 01:06:27

这又如何呢?

编辑用户的 .bashprofile 添加:

export LAST_DAY_OF_MONTH=$(cal | awk '!/^$/{ print $NF }' | tail -1)

然后将此条目添加到 crontab:

mm hh * * 1-7 [[ $(date +'%d') -eq $LAST_DAY_OF_MONTH ]] && /absolutepath/myscript.sh

What about this?

edit user's .bashprofile adding:

export LAST_DAY_OF_MONTH=$(cal | awk '!/^$/{ print $NF }' | tail -1)

Then add this entry to crontab:

mm hh * * 1-7 [[ $(date +'%d') -eq $LAST_DAY_OF_MONTH ]] && /absolutepath/myscript.sh
才能让你更想念 2024-11-17 01:06:27

每月的最后一天可能是 28-31,具体取决于月份(二月、三月等)。但是,在这两种情况下,第二天始终是下个月的 1 日。因此,我们可以使用它来确保我们始终在一个月的最后一天运行一些作业,使用下面的代码:

0 8 28-31 * * [ "$(date +%d -d tomorrow)" = "01" ] && /your/script.sh

The last day of month can be 28-31 depending on what month it is (Feb, March etc). However in either of these cases, the next day is always 1st of next month. So we can use that to make sure we run some job always on the last day of a month using the code below:

0 8 28-31 * * [ "$(date +%d -d tomorrow)" = "01" ] && /your/script.sh
橘和柠 2024-11-17 01:06:27

使用下面的代码在 PHP 中的该月的最后一天运行 cron

$commands = '30 23 '.date('t').' '.date('n').' *';

Use the below code to run cron on the last day of the month in PHP

$commands = '30 23 '.date('t').' '.date('n').' *';
原野 2024-11-17 01:06:27

不确定其他语言,但在 javascript 中是可能的。

如果您需要作业在每月的第一天之前完成,node-cron 将允许您设置时区 - 您必须设置 UTC+12:00,如果世界上大部分地区的作业时间不太长将在月初之前得到结果。

Not sure of other languages but in javascript it is possible.

If you need your job to be completed before first day of month node-cron will allow you to set timezone - you have to set UTC+12:00 and if job is not too long most of the world will have results before start of their month.

遗失的美好 2024-11-17 01:06:27

将 cron 安排在每个下个月的第一天的更好方法

这将在上午 12:00 运行命令 foo。

0 0 1 * * /usr/bin/foo

Better way to schedule cron on every next month of 1st day

This will run the command foo at 12:00AM.

0 0 1 * * /usr/bin/foo

〃安静 2024-11-17 01:06:27

如果在午夜和凌晨 1 点之间运行,请谨慎使用“日期”程序中的“昨天”、“今天”、“1 天”,因为通常这些实际上意味着“24 小时”,当夏令时更改导致 23 小时时,这将是两天天。我使用“date -d '1am -12 hour' ”

Be cautious with "yesterday", "today", "1day" in the 'date' program if running between midnight and 1am, because often those really mean "24 hours" which will be two days when daylight saving time change causes a 23 hour day. I use "date -d '1am -12 hour' "

雪落纷纷 2024-11-17 01:06:27

如果日期字段可以接受第 0 天,那么这个问题就可以很简单地解决。例如。天文学家使用零日来表示上个月的最后一天。因此,

00 08 00 * * /usr/local/sbin/backup

将以简单易行的方式完成这项工作。

If the day-of-the-month field could accept day zero that would very simply solve this problem. Eg. astronomers use day zero to express the last day of the previous month. So

00 08 00 * * /usr/local/sbin/backup

would do the job in simple and easy way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文