Utk*_*maz 83 cron automation posix
我需要创建一个将在每个月的最后一天运行的cron作业.我将从cpanel创建它.
任何帮助表示赞赏.谢谢
pax*_*blo 153
可能最简单的方法是简单地完成三个独立的工作:
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
Run Code Online (Sandbox Code Playgroud)
那将是2月28日,即使在闰年,所以,如果这是一个问题,你需要找到另一种方式.
但是,在每个月的第一天尽快运行工作通常更加容易和正确,例如:
0 0 1 * * myjob.sh
Run Code Online (Sandbox Code Playgroud)
并修改脚本来处理以前一个月的数据.
这可以消除您在确定哪一天是该月的最后一天时可能遇到的任何麻烦,并且还可以确保该月的所有数据都可用,假设您正在处理数据.在这个月的最后一天五分钟到午夜的运行可能会发现你错过了当时和午夜之间发生的任何事情.
无论如何,这是通常的方式,对于大多数月末的工作.
如果你还是真的要在每月的最后一天运行它,一个选择是简单地检测,如果明天是第一个(无论是作为脚本的一部分,或者在crontab本身).
所以,像:
55 23 28-31 * * [[ "$(date --date=tomorrow +\%d)" == "01" ]] && myjob.sh
Run Code Online (Sandbox Code Playgroud)
应该是一个好的开始,假设你有一个相对聪明的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;
}
Run Code Online (Sandbox Code Playgroud)
然后使用(假设你称它为tomdom"明天的一天"):
55 23 28-31 * * [[ "$(tomdom)" == "1" ]] && myjob.sh
Run Code Online (Sandbox Code Playgroud)
虽然你可能需要考虑增加错误检查,因为两者time()并mktime()可以返回-1,如果出现错误.出于简单的原因,上面的代码没有考虑到这一点.
小智 48
可以使用类似于上述方法之一的略短的方法.那是:
[ $(date -d +1day +%d) -eq 1 ] && echo "last day of month"
Run Code Online (Sandbox Code Playgroud)
此外,crontab条目可以更新为仅在28日到31日检查,因为它在该月的其他日子无意义地运行它.哪个会给你:
0 23 28-31 * * [ $(date -d +1day +%d) -eq 1 ] && myscript.sh
Run Code Online (Sandbox Code Playgroud)
Tom*_*son 20
设置一个cron作业,在该月的第一天运行.然后将系统的时钟更改为提前一天.
Pio*_*hen 10
在维基百科之后,这个怎么样?
55 23 L * * /full/path/to/command
Run Code Online (Sandbox Code Playgroud)
Thu*_*bit 10
适应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
Run Code Online (Sandbox Code Playgroud)
Dan*_*man 10
对于 AWS Cloudwatch cron 实施(调度 Lambdas 等),这有效:
55 23 L * ? *
Run Code Online (Sandbox Code Playgroud)
每月最后一天晚上 11:55 运行。
您可以设置一个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
Run Code Online (Sandbox Code Playgroud)
我从这个网站找到了如下解决方案(在该月的最后一天)。
0 0 0 L * ? *
Run Code Online (Sandbox Code Playgroud)
克罗恩详细信息:
Seconds Minutes Hours Day Of Month Month Day Of Week Year
0 0 0 L * ? *
Run Code Online (Sandbox Code Playgroud)
要交叉验证上述表达式, 请单击此处,它会提供如下所示的输出。
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
Run Code Online (Sandbox Code Playgroud)
对于基于@Indie解决方案的crontab中的一种更安全的方法(使用date+的绝对路径$()不适用于所有crontab系统):
0 23 28-31 * * [ `/bin/date -d +1day +\%d` -eq 1 ] && myscript.sh
Run Code Online (Sandbox Code Playgroud)
一些 cron实现支持"L"标志来表示该月的最后一天.
如果您很幸运能够使用其中一种实现,那就很简单:
0 55 23 L * ?
Run Code Online (Sandbox Code Playgroud)
那将在每个月的最后一天晚上11:55运行.
http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger
#########################################################
# 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"
Run Code Online (Sandbox Code Playgroud)