首页 > 解决方案 > 本月第 n 个星期六的 Linux crontab

问题描述

我喜欢在除周六以外的所有工作日都跑回来。我的 crontab 条目

30 16 * * 1,2,3,4,5 ./backup.sh

此条目工作正常。另外,我喜欢在第 1、第 3 个星期六回来。如果一个月内有任何 5th Sutarday 可用,则应运行备份。crontab 的条目是什么?我猜

30 16 1-7, 15-21, 29-31 * 6 ./backup.sh

我对吗?

标签: cron

解决方案


我对吗?

不,你不正确。crontab 手册指出:

注意:可以在以下两个字段中指定命令的执行日期 day of monthday of week。如果两个字段都受到限制(即不包含“*”字符),则当任一字段与当前时间匹配时,将运行该命令。例如, 30 4 1,15 * 5将导致在每个月的 1 日和 15 日以及每个星期五的凌晨 4:30 运行命令。

那么我们该怎么做呢?

如果你想确定它是一个月的哪个星期六,即是一个月的第一个、第二个或第三个星期六,你所要做的就是查看星期六的工作日并进行以下整数计算:

D=$(date "+%d")
echo $(( (D-1)/7 + 1 ))

该值将返回相应的数字。这不仅适用于星期六,也适用于任何工作日。

由于 OP 希望 cron 在第 1 个、第 3 个和可能的第 5 个星期六工作,它实际上声明 cron 在每个奇数星期六运行:

D=$(date "+%d")
echo $(( ((D-1)/7 + 1) % 2 ))

使用它作为附加测试,允许我们将 cron 编写为:

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
# |  |  |  |  |
# *  *  *  *  *   command to be executed

 30 16  *  *  6   (( (($(date "+\%d") - 1)/7 + 1) % 2 == 1 )) && command

推荐阅读