如何设置一个cron,以便从10 days
开始每16th January
执行一次?这样就够了吗?
30 7 16-15/10 * * command >/dev/null
以上内容从7.30 AM
,16th of every month
开始,到next month 15th
结束,并重复10 days
。我不认为我上面的内容是正确的。任何人都可以告诉我如何设置cron,以便考虑月末,并且从10 days
开始执行每个16th January this year 2016
命令。
答案 0 :(得分:0)
0 30 7 1/10 * ? * command >/dev/null
上述快递的输出是,
Saturday, January 16, 2016 7:30 AM
1. Thursday, January 21, 2016 7:30 AM
2. Sunday, January 31, 2016 7:30 AM
3. Monday, February 1, 2016 7:30 AM
4. Thursday, February 11, 2016 7:30 AM
5. Sunday, February 21, 2016 7:30 AM
表达式的输出
i.e 30 7 16-15/10 * * command >/dev/null
2016-01-15 07:30:00
2016-02-15 07:30:00
2016-03-15 07:30:00
2016-04-15 07:30:00
2016-05-15 07:30:00
2016-06-15 07:30:00
2016-07-15 07:30:00
2016-08-15 07:30:00
2016-09-15 07:30:00
2016-10-15 07:30:00
最接近的语法是这样的:
30 7 1-30/10 * *
30 7 1-31/10 * *
30 7 1-28/10 * *
30 7 1-29/10 * *
测试cron表达式
答案 1 :(得分:0)
正如威廉所说,cron本身无法处理这种复杂性。但是,您可以更频繁地运行cron作业,并为逻辑使用其他内容。例如;
30 7 16-31 1 * date '+\%j' | grep -q '0$' && yourcommand
30 7 * 2-12 * date '+\%j' | grep -q '0$' && yourcommand
此日期格式字符串打印一年中的某一天,从001到365. grep -q
将执行模式匹配,不打印结果,但会根据找到的内容返回失败的成功。每隔10天,一年中的一天结束为零。在那些日子里,yourcommand
开始运行。
年度滚动存在问题。更复杂的替代方案可能是在date '+%s'
(第二纪元)的产品上执行类似的grep,但是您需要通过grep
进行数学运算以将秒数转换为几天进行分析。这可能有效(你应该测试):
SHELL=/bin/bash
30 7 * * * echo $(( $(date '+%s') / 86400 )) | grep '0$' && yourcommand
(当然也加上你的1月16日的逻辑。)
这依赖于shell算法只能处理整数这一事实。 shell简单地截断而不是舍入。
<强>更新强>
在对另一个答案的评论中,您澄清了您的要求:
该命令应于1月16日开始执行,并继续如1月26日,2月5日,2月15日等等 - jai
为此,第二纪元的方法可能是正确的方向。
% date -v1m -v16d -v7H -v30M -v0S '+%s'
1452947400
(我在FreeBSD中,因此date
的这些参数。)
SHELL=/bin/bash
30 7 * * * [[ $(( ($(date '+\%s') - 1452947400) \% 864000 )) == 0 ]] && yourcommand
此表达式从当前时间减去1月16日上午7:30(我的时区)的第二纪元,并测试结果差异是否可被10天整除。如果是,则表达式计算为true并运行您的命令。请注意,对于$ x的任何值,$(( 0 % $x ))
的计算结果为0。
如果cron特别忙,并且无法在数学运算的一秒钟内完成工作,那么这可能会出错。
如果你想让它更复杂(甚至可能是这个复杂),我建议你将逻辑移到一个单独的shell脚本来处理日期比较数学。特别是如果你打算添加一个软糖因子以允许作业错过他们的1秒窗口......这可能是多行脚本,这在单个cronjob条目中难以维护。
答案 2 :(得分:0)
观察:cron的数学功能几乎不存在。 Unix工具的数学功能是无穷无尽的。
结论:将问题从cron域移到shell域。
解决方案:每天在crontab中使用30 7 * * * /path/to/script
运行此操作:
#!/bin/sh
PATH=$(/usr/bin/getconf PATH)
if test $(($(date +%j) % 10)) = 6; then
your_command
fi
这测试一年中的模10是否为6,就像是1月16日(1月6日已经过去......)。
在盒子外思考: 修正您的要求。说服那些有趣的10天周期接受7天周期的人。对于cron来说要容易得多。这符合KISS原则。