我在RedHat上使用Bash。我需要安排一个cron工作在每个月的第一个星期日上午9点运行。我怎么能这样做?
答案 0 :(得分:128)
您可以在crontab
文件中输入类似内容:
00 09 * * 7 [ $(date +\%d) -le 07 ] && /run/your/script
date +%d
为您提供当天的号码,然后您可以检查当天是否小于或等于7.如果是,请运行您的命令。
如果您仅在星期日运行此脚本,则应表示它仅在该月的第一个星期日运行。
请记住,在crontab
文件中,应转义date
命令的格式设置选项。
答案 1 :(得分:12)
您需要结合两种方法:
a)使用cron
每周日上午9:00开始工作。
00 09 * * 7 /usr/local/bin/once_a_week
b)在once_a_week
的开头,计算日期并通过shell,Python,C / C ++,...和1到7之间的测试来提取月份的日期。如果是这样,执行真实的脚本;如果没有,请默默退出。
答案 2 :(得分:5)
一个hacky解决方案:让你的cron作业每个星期天运行,但让你的脚本在开始时检查日期,如果当月的日期是> 1,则立即退出。 7 ...
答案 3 :(得分:5)
第1个星期一,第3个星期二,最后一个星期日,任何事情......运行cron任务。
http://xr09.github.io/cron-last-sunday/
只需将run-if-today
脚本放在路径中,然后将其与cron一起使用。
30 6 * * 6 root run-if-today 1 Sat && /root/myfirstsaturdaybackup.sh
run-if-today
脚本只返回0(bash值为True),如果它是正确的日期。
编辑:
现在界面更简单,只有一个参数用于周数。
# run every first saturday
30 6 * * 6 root run-if-today 1 && /root/myfirstsaturdaybackup.sh
# run every last sunday
30 6 * * 7 root run-if-today L && /root/lastsunday.sh
答案 4 :(得分:5)
值得注意的是,看起来最明显的解决此问题的方法无效有效。
您可能会认为您可以编写一个crontab条目,将星期几指定为0(代表星期日),将星期几指定为1-7,就像这样...
# This does NOT work.
0 9 1-7 * 0 /path/to/your/script
...,但是由于an eccentricity of how Cron handles crontab lines with both a day-of-week and day-of-month specified,此操作无效,并且实际上会在每月的1号,2号,3号,4号,5号,6号和7号运行(不管什么)它们是星期几),分别是每月的 和。
这就是为什么您会看到建议与[ ... ]
一起使用date
检查以建立这样的规则的原因-在crontab中指定星期几并使用{{3} }和[
,以便在运行脚本之前检查月份的天数是否小于等于7,如date
所示,或者在crontab中指定月份的天数范围并使用{ {1}}和[
检查运行前的星期几,例如:
date
如果要确保您的crontab行不管您在哪个操作系统上使用,都应牢记一些最佳做法:
# This DOES work.
0 9 1-7 * * [ $(date +\%u) = 7 ] && /path/to/your/script
而非=
进行比较。由于不是所有的shell都使用支持==
运算符的[
实现,所以它更加可移植。==
到%u
的说明符来获取星期几,而不是date
运算符,因为%a
根据区域设置%a
正在运行。date
,而不要使用date
或/bin/date
,因为/usr/bin/date
实用程序在不同系统上的位置不同。答案 5 :(得分:4)
这也适用于工作日的名称:
0 0 1-7 * * [ "$(date '+\%a')" == "Sun" ] && /usr/local/bin/urscript.sh
但是,
[ "$(date '+\%a')" == "Sun" ] && echo SUNDAY
将在comandline上 FAIL
答案 6 :(得分:0)
也许使用cron.hourly来调用另一个脚本。然后该脚本将检查它是否是本月的第一个星期日和上午9点,如果是,则运行您的程序。听起来对我来说最合适: - )。
答案 7 :(得分:0)
如果您不希望cron每天或每个星期天运行您的工作,您可以编写一个运行代码的包装器,确定下一个第一个星期日,并安排自己在该日期运行。
然后为该月的下一个第一个星期日安排该包装器。之后它将自己处理所有事情。
代码就像(强调某些东西......没有完成错误检查):
#! /bin/bash
#We run your code first
/path/to/your/code
#now we find the next day we want to run
nskip=28 #the number of days we want to check into the future
curr_month=`date +"%m"`
new_month=`date --date='$nskip days' +"%m"`
if [[ curr_month = new_month ]]
then
((nskip+=7))
fi
date=`date --date='$nskip days' +"09:00AM %D` #you may need to change the format if you use another scheduler
#schedule the job using "at"
at -m $date < /path/to/wrapper/code
逻辑很容易找到下一个第一个星期天。由于我们从当月的第一个星期日开始,添加28将使我们在本月的最后一个星期日或下个月的第一个星期日。如果是当月,我们将增加到下一个星期日(将在下个月的第一周)。
我用“at”。我不知道这是不是在作弊。但主要的想法是找到下一个第一个星期天。您可以替换之后想要的任何调度程序,因为您知道要运行作业的日期和时间(不同的调度程序可能需要不同的日期语法)。
答案 8 :(得分:-1)
答案 9 :(得分:-3)
00 09 1-7 * 0 / usr / local / bin / once_a_week
每月前7天的每个星期日