从1月16日开始,每10天设一个cron

时间:2016-01-13 06:03:15

标签: linux unix cron crontab cron-task

如何设置一个cron,以便从10 days开始每16th January执行一次?这样就够了吗?

30 7 16-15/10 * * command >/dev/null

以上内容从7.30 AM16th of every month开始,到next month 15th结束,并重复10 days。我不认为我上面的内容是正确的。任何人都可以告诉我如何设置cron,以便考虑月末,并且从10 days开始执行每个16th January this year 2016命令。

3 个答案:

答案 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 * *

您可以在http://cron.schlitt.info/

测试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原则。