每隔一周通过cron运行脚本


12

我已经就如何做到这一点进行了大量研究,而且我发现cron并没有直接的方式来工作,例如隔周四。

现在,我倾向于制作一个仅每周运行一次的脚本,该脚本在运行时会触摸一个“标志”文件,如果运行并且文件已经存在,则删除该文件(而不执行每两周一次)。

我的问题是,还有其他更优雅或更简单的方法来实现bash脚本每隔一周自动运行一次的目标吗?

谢谢!


1
您可以使用ISO周数来代替标志文件。(例如strftime的%V。)

@Roger:我想你的意思是在脚本中有条件的。
暂停,直到另行通知。

@Dennis:不必一定要(例如,查看我的答案如何在脚本之外进行检查),但是我的主要观点是,它要简单得多,并且不需要文件系统中的任何状态。但是,我意识到它有一个类似的缺点,因为检查月份的一天:有些年份53周,部分52

Answers:


11
0 0 * * Thu bash -c '(($(date +\%s) / 86400 \% 14))' && your-script

我用bash做数学,因为我很懒。切换到您喜欢的任何位置。我利用1970年1月1日为星期四的机会;在一周的其他几天,您必须应用抵消。Cron需要逃脱百分号。

快速检查:

function check {
  when=$(date --date="$1 $(($RANDOM % 24)):$(($RANDOM % 60))" --utc)
  echo -n "$when: "
  (($(date +%s --date="$when") / 86400 % 14)) && echo run || echo skip
}

for start in "2010-12-02" "2011-12-01"; do
  for x in $(seq 0 12); do
    check "$start + $(($x * 7)) days"
  done
  echo
done

请注意,我已经选择了随机时间来显示它可以在星期四的任何时间运行,并且选择了跨越年份界限的日期,还包括四个星期四和五个星期四的月份。

输出:

Thu Dec  2 06:19:00 UTC 2010: run
Thu Dec  9 23:04:00 UTC 2010: skip
Thu Dec 16 05:37:00 UTC 2010: run
Thu Dec 23 12:49:00 UTC 2010: skip
Thu Dec 30 03:59:00 UTC 2010: run
Thu Jan  6 11:29:00 UTC 2011: skip
Thu Jan 13 13:23:00 UTC 2011: run
Thu Jan 20 20:33:00 UTC 2011: skip
Thu Jan 27 16:48:00 UTC 2011: run
Thu Feb  3 17:43:00 UTC 2011: skip
Thu Feb 10 05:49:00 UTC 2011: run
Thu Feb 17 08:46:00 UTC 2011: skip
Thu Feb 24 06:50:00 UTC 2011: run

Thu Dec  1 21:40:00 UTC 2011: run
Thu Dec  8 23:24:00 UTC 2011: skip
Thu Dec 15 22:27:00 UTC 2011: run
Thu Dec 22 02:47:00 UTC 2011: skip
Thu Dec 29 12:44:00 UTC 2011: run
Thu Jan  5 17:59:00 UTC 2012: skip
Thu Jan 12 18:31:00 UTC 2012: run
Thu Jan 19 04:51:00 UTC 2012: skip
Thu Jan 26 08:02:00 UTC 2012: run
Thu Feb  2 17:37:00 UTC 2012: skip
Thu Feb  9 14:08:00 UTC 2012: run
Thu Feb 16 18:50:00 UTC 2012: skip
Thu Feb 23 15:52:00 UTC 2012: run

2
自纪元固有以来是秒,而cron在本地时间运行。如果您的系统时区不是UTC,则会导致混乱。(“为什么不运行?哦,它已经是UTC的星期五了”)。夏时制的存在使解决这一问题变得更加困难(尽管并非不可能,因为日期校准会告诉您当前的UTC偏移量)
derobert 2012年

5

一种方法是at在运行Linux的情况下使用该实用程序。您可以将其放在脚本的末尾:

at X + 2 weeks -f myscript

其中X是要在运行脚本的时间。要初始化,只需at在您想第一次运行它的时间进行调用,然后上面的语句将继续更新您的计划调用。


如果这将是一个长期解决方案,虽然我会在脚本中创建一个函数来确定是否需要运行,但我不建议运行此函数
Paul

3

如果您可以anacron在系统上使用,那么事情将会简单得多。要使用anacron它,必须先安装它,而且还必须具有root用户访问权限。它不适用于较旧的系统(例如RHEL 5.x),而较旧的ancron版本仅在启动时运行。它确实适用于较新的系统(即RHEL 6.x)。

使用anacron,可以以更灵活的方式安排作业,例如,每周运行一次X作业。anacron当计算机可用时也运行作业,即,您不必考虑系统何时启动或关闭。

要每两周运行一次脚本,必须在/ etc / anacrontab中添加类似于以下内容的行:

14 5 myScript script.sh

查看手册页以了解详细信息。


anacron显然,使用IMO是最干净的解决方案(除非它对某些人造成某些不良后果)。
2010年

0

我不确定是否有一种更优雅的方法来定义每隔一周,但这可能对您有用。

00 06 1-7,15-21 * * test `date +\%a` = Thu && /path/to/script

这将在该月的第一个和第三个星期四的6:00 am启动脚本。


2
但是,如果有一个月有3个星期四,那将跳过一周。
David Z

1
有一个只有三个星期四的月份吗?尽管如果有5个星期四,我可以跳过一周。可以将其更新为1-7,15-21,29-31,但是如果最后一组有任何匹配,
它将连续运行

1
到3个星期四,您是说该脚本将运行3个星期四,而不是3个星期四吗?我可能是第一次看错了。
2010年

0

我将每周运行一次,并让脚本检查周数是否为奇数:如果是,则退出。

从12月到1月,这需要更多的思考才能起作用。

也许脚本设置了“最后一次成功运行”标志文件。脚本启动时,请检查标志文件在14天前的最后修改。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.