如何在Linux中每周指定时间段内仅运行一次任务?
解决每周周四指定时间段内仅运行一次脚本的问题
你提到用0 17 * * 4 /path/my_ba.sh的crontab命令没实现“仅运行一次”的要求,大概率是担心意外重复触发(比如服务器17点宕机后重启补跑、crontab服务重启、脚本被误手动执行),或者你其实想在17:00-21:00的窗口内只要执行一次即可(不管具体几点,只要在窗口内且仅一次)。下面给你几个针对性的解决方案:
方案1:锁定整点执行,杜绝重复
你的原crontab命令本身是每周四17点执行一次,但如果要彻底避免重复执行的风险,给脚本加个按周生成的锁文件是最稳妥的办法:
修改你的my_ba.sh脚本,开头加入锁检查逻辑:
#!/bin/bash # 用「年份+周数」命名锁文件,确保每周仅生成一个唯一锁 LOCKFILE="/tmp/my_script_$(date +%Y%U).lock" # 如果锁文件存在,说明本周已经执行过,直接退出 if [ -f "$LOCKFILE" ]; then echo "本周脚本已执行过,退出..." exit 0 fi # 创建锁文件,标记本周已执行 touch "$LOCKFILE" # -------------------------- # 这里放你的脚本核心业务逻辑 # -------------------------- # 可选:如果脚本执行失败需要重试,可以在失败时删除锁文件 # 比如在核心逻辑后加: # if [ $? -ne 0 ]; then # rm "$LOCKFILE" # fi
crontab依然保留原命令:
0 17 * * 4 /path/my_ba.sh
方案2:窗口内灵活执行,确保仅一次
如果你的需求是「只要在周四17:00-21:00之间执行一次即可」(比如服务器17点宕机,重启后在窗口内自动补执行),可以让crontab在窗口内每分钟检查一次,结合锁文件确保仅执行一次:
修改脚本的锁文件逻辑(和方案1一致),再加上时间窗口检查:
#!/bin/bash LOCKFILE="/tmp/my_script_$(date +%Y%U).lock" if [ -f "$LOCKFILE" ]; then exit 0 fi # 检查当前时间是否在17:00-21:00之间 CURRENT_HOUR=$(date +%H) if [ "$CURRENT_HOUR" -ge 17 ] && [ "$CURRENT_HOUR" -lt 21 ]; then touch "$LOCKFILE" # -------------------------- # 这里放你的脚本核心业务逻辑 # -------------------------- fi
设置crontab让脚本在周四17:00-20:59之间每分钟执行一次:
*/1 17-20 * * 4 /path/my_ba.sh
这样只要服务器在窗口内处于运行状态,脚本就会自动执行一次,之后不再触发。
方案3:离线服务器适配(用anacron)
如果你的服务器经常离线,anacron会在系统开机后检查错过的定时任务并补执行,搭配锁文件也能实现每周仅一次:
编辑/etc/anacrontab,添加一行配置:
7 10 weekly_my_script /path/my_ba.sh
7:表示每7天执行一次(即每周)10:系统开机后延迟10分钟执行weekly_my_script:任务标识(自定义即可)
同样要在my_ba.sh里加入方案1的按周锁文件逻辑,防止anacron重复执行。
内容的提问来源于stack exchange,提问作者Uncle Ben Ben
相关产品推荐
相关产品推荐

