从 1 月 16 日开始每 10 天设置一个 cron
Set a cron every 10 days starting from 16th January
如何设置一个 cron 以从 16th January
开始每隔 10 days
执行一次?这够了吗?
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 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 表达式 http://cron.schlitt.info/
正如 William 所建议的,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
将进行模式匹配,不打印结果,但 return 成功或失败它发现的基础。每隔 10 天,一年中的某一天就会以零结束。在那些日子里,yourcommand
得到 运行。
roll-over 年份有问题。一个更复杂的替代方案可能是对 date '+%s'
(纪元秒)的乘积执行类似的 grep,但您需要进行数学运算将秒数转换为天数以供 grep
分析。这可能有效(你应该测试):
SHELL=/bin/bash
30 7 * * * echo $(( $(date '+%s') / 86400 )) | grep '0$' && yourcommand
(当然也加上你的 1 月 16 日逻辑。)
这依赖于 shell 算术只能处理整数这一事实。 shell 只是 t运行 分类而不是四舍五入。
更新
在对另一个答案的评论中,您阐明了您的要求:
The command should start executing on January 16th, and continue like on January 26th, February 5th, February 15th and so on – jai
为此,epoch-second 方法可能是正确的方向。
% date -v1m -v16d -v7H -v30M -v0S '+%s'
1452947400
(我在 FreeBSD 中,因此这些论点 date
。)
SHELL=/bin/bash
30 7 * * * [[ $(( ($(date '+\%s') - 1452947400) \% 864000 )) == 0 ]] && yourcommand
此表达式从当前时间减去 7:30AM 1 月 16 日(我的时区)的纪元秒,并测试所得差异是否可以被 10 天整除。如果是,则表达式的计算结果为真,您的命令为 运行。请注意,对于 $x.
的任何值,$(( 0 % $x ))
的计算结果为 0
如果 cron 特别忙并且无法在数学计算出来的那一秒内完成您的工作,这可能容易出错。
如果你想让它变得更复杂(甚至可能是 this 复杂),我建议你将逻辑移动到一个单独的 shell 脚本中以处理日期比较数学。特别是如果您计划添加一个软糖因素以允许作业错过其 1 秒 window .. 这可能是多行脚本,这在单个 cronjob 条目中维护起来很尴尬。
观察:cron 的数学能力仅次于non-existent。 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
这测试 day-of-year 模 10 是否为 6,就像 1 月 16 日一样(而 1 月 6 日已经过去了......)。
跳出框框思考:
解决您的要求。说服想出那个有趣的 10 天周期的人接受 7 天周期。 cron 就容易多了。这是遵循 KISS 原则。
如何设置一个 cron 以从 16th January
开始每隔 10 days
执行一次?这够了吗?
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 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 表达式 http://cron.schlitt.info/
正如 William 所建议的,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
将进行模式匹配,不打印结果,但 return 成功或失败它发现的基础。每隔 10 天,一年中的某一天就会以零结束。在那些日子里,yourcommand
得到 运行。
roll-over 年份有问题。一个更复杂的替代方案可能是对 date '+%s'
(纪元秒)的乘积执行类似的 grep,但您需要进行数学运算将秒数转换为天数以供 grep
分析。这可能有效(你应该测试):
SHELL=/bin/bash
30 7 * * * echo $(( $(date '+%s') / 86400 )) | grep '0$' && yourcommand
(当然也加上你的 1 月 16 日逻辑。)
这依赖于 shell 算术只能处理整数这一事实。 shell 只是 t运行 分类而不是四舍五入。
更新
在对另一个答案的评论中,您阐明了您的要求:
The command should start executing on January 16th, and continue like on January 26th, February 5th, February 15th and so on – jai
为此,epoch-second 方法可能是正确的方向。
% date -v1m -v16d -v7H -v30M -v0S '+%s'
1452947400
(我在 FreeBSD 中,因此这些论点 date
。)
SHELL=/bin/bash
30 7 * * * [[ $(( ($(date '+\%s') - 1452947400) \% 864000 )) == 0 ]] && yourcommand
此表达式从当前时间减去 7:30AM 1 月 16 日(我的时区)的纪元秒,并测试所得差异是否可以被 10 天整除。如果是,则表达式的计算结果为真,您的命令为 运行。请注意,对于 $x.
的任何值,$(( 0 % $x ))
的计算结果为 0
如果 cron 特别忙并且无法在数学计算出来的那一秒内完成您的工作,这可能容易出错。
如果你想让它变得更复杂(甚至可能是 this 复杂),我建议你将逻辑移动到一个单独的 shell 脚本中以处理日期比较数学。特别是如果您计划添加一个软糖因素以允许作业错过其 1 秒 window .. 这可能是多行脚本,这在单个 cronjob 条目中维护起来很尴尬。
观察:cron 的数学能力仅次于non-existent。 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
这测试 day-of-year 模 10 是否为 6,就像 1 月 16 日一样(而 1 月 6 日已经过去了......)。
跳出框框思考: 解决您的要求。说服想出那个有趣的 10 天周期的人接受 7 天周期。 cron 就容易多了。这是遵循 KISS 原则。