我正在尝试安排一个 cron 作业,其要求是该作业必须每天、每月、每分钟和每小时运行,除了每个月的第二个和第四个星期日凌晨 1 点到 3 点。
我们有办法做到吗?我尝试过使用下面的方法,但没有成功:
* 0-1,3-23 1-3,5-17,19-31 * 1-6
答案1
单独使用cron
此类特定时间例外是不可能配置的。相反,您应该在脚本中进行检查,以便在遇到这些异常时脚本不会运行。例如,这可能看起来像这样:
#!/bin/sh
# If it's sunday ...
if [ "$(date +%u)" = "7" ]; then
# and it's the 2nd or ...
if ( [ "$(date +%e)" -gt "7" ] && [ "$(date +%e)" -lt "15" ] ) || \
# or the 4th sunday of the month ...
( [ "$(date +%e)" -gt "21" ] || [ [ "$(date +%e)" -lt "29" ] ); then
# look if it's between 1 and 3 AM ...
if [ "$(date +%k)" -ge "1" ] && [ "$(date +%k)" -le "3" ]; then
# exit the script if all of the above have met
exit
fi
fi
fi
# normal script continues here
将其添加到脚本的开头。
答案2
如果您使用 dcron,您可以做的是设置一个作业,在您想要排除的整个持续时间内执行:
# crontab
# MIN HOUR DAY MONTH DAYOFWEEK COMMAND
0 1 1-7,15-21 * 7 ID=naptime /path/to/naptime.sh
午睡时间.sh:
#!/bin/sh
# Exit unless Sunday
if [ $(date +%u) -ne 7 ] ; then
exit
fi
sleep 2h
然后,您可以将目标作业设置为“依赖于”午睡时间作业:
# crontab
* * * * * FREQ=1m AFTER=naptime/1m /path/to/job.sh
从定时任务(1):
作业可以“依赖”,或者等到其他作业成功完成之后。考虑以下 crontab:
* * * * * ID=job4 FREQ=1d first_command * * * * * ID=job5 FREQ=1h AFTER=job4/30m second_command
这里,每当 job5 即将运行时,如果 job4 计划在接下来的 30 分钟(30m)内运行,则 job5 将首先等待其成功完成。
(如果 job4 没有成功完成怎么办?如果 job4 返回时退出代码为 EAGAIN,则 job5 将继续等待,直到重试 job4 - 即使不会在一小时内重试。如果 job4 返回时带有任何其他非零退出代码,job5 将从队列中删除而不运行。)
答案3
首先,每分钟运行一次脚本:
* * * * * /usr/local/script.sh
然后将逻辑放入其中,使其立即退出,如果是:
- 第二个星期日或第四个星期日,或
- 凌晨 1 点至 3 点
此示例脚本依赖于ncal
和awk
:
#!/bin/bash
second_sunday=$(ncal -h | awk '/Su/ {print $(NF-2)}')
fourth_sunday=$(ncal -h | awk '/Su/ {print $(NF)}')
if [[ $(date +'%d') -eq $second_sunday ]] || [[ $(date +'%d') -eq $fourth_sunday ]]
then exit 0
else
if [[ $(date +'%H') -ge 01 ]] && [[ $(date +'%H') -lt 04 ]]
then exit 0
fi
fi