每30秒运行一次cron

Mat*_*iby 270 ubuntu cron scheduled-tasks

好的,我有一个cron,我需要每30秒运行一次.

这是我有的:

*/30 * * * * /bin/bash -l -c 'cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\'''
Run Code Online (Sandbox Code Playgroud)

它运行,但这是每30分钟还是30秒运行一次?

此外,我一直在阅读如果我经常运行它,cron可能不是最好的工具.还有其他更好的工具,我可以在Ubuntu 11.04上使用或安装,这将是一个更好的选择吗?有没有办法修复上面的cron?

pax*_*blo 678

你必须*/30几分钟符-这意味着每分钟,但与30步骤(换句话说,每半小时一班).由于cron不会达到亚分钟分辨率,您需要找到另一种方法.

一种可能性,虽然它有点像kludge,但是有两个工作,一个偏移30秒:

* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )
Run Code Online (Sandbox Code Playgroud)

两个cron工作实际上每分钟都在运行,但后者将在执行工作的"肉"之前等待半分钟/path/to/executable.

  • 这是一个很好的解决方法,所以我认为它超越了它的kludginess (19认同)
  • @ rubo77,只有花了不到一秒的时间才能运行:-)如果用了29秒,就会发生在0:00:00,0:00.59,0:01:00,0:01:59等等. (14认同)
  • 第二行周围的圆括号是什么? (3认同)
  • 这是一个很好的解决方案,对于某些需要在数分钟之内执行的任务,否则会严重降低有效性。谢谢。 (2认同)

wil*_*ser 61

你不能.Cron的粒度为60秒.

* * * * * cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\''
* * * * * sleep 30 && cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\''
Run Code Online (Sandbox Code Playgroud)

  • 我的意思是,使用 `&&` 而不是 `( ; )`。 (2认同)
  • 对不起。不,有区别;`&&` 运算符短路,因此如果前一个命令失败,则不会执行链中的下一个命令。 (2认同)

Mar*_*nto 36

Cron的粒度只需几分钟,并不是为了每秒钟唤醒x而运行一些东西.在循环中运行重复任务,它应该做你需要的:

#!/bin/env bash
while [ true ]; do
 sleep 30
 # do what you need to here
done
Run Code Online (Sandbox Code Playgroud)

  • 请记住,这不是_quite_相同.如果作业需要25秒(例如),它将每55秒而不是每30秒启动一次.这可能没关系,但你应该意识到可能的后果. (52认同)
  • 您可以在后台运行该作业,然后它将在几乎30秒内运行. (7认同)
  • 您可以执行`sleep $ remainingTime`,其中remainingTime为30减去作业所用的时间(如果花费> 30秒,则将其限制为零).因此,您需要花时间在实际工作之前和之后,并计算差异. (2认同)

And*_*rew 22

不需要两个cron条目,你可以把它放在一个:

* * * * * /bin/bash -l -c "/path/to/executable; sleep 30 ; /path/to/executable"
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下:

* * * * * /bin/bash -l -c "cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\'' ; sleep 30 ; cd /srv/last_song/releases/20120308133159 && script/rails runner -e production '\''Song.insert_latest'\''"

  • 注意:如果脚本运行时间不到一秒,则此操作只能正确运行 (11认同)
  • Rubo - 如果作业需要几秒钟(而不是毫秒或微秒)才能完成,那么您不会每 30 秒运行一次才能每分钟运行两次。所以是的,从 30 开始,然后从中减去每次运行的大约秒数,如果大于 1 秒。 (2认同)
  • 如果您想单独接收每次运行的错误报告,这也无济于事。 (2认同)

Gus*_*uss 18

如果您正在运行带有SystemD的最新Linux操作系统,则可以使用SystemD Timer单元以所需的任何粒度级别(理论上可降至纳秒级)运行脚本,并且-如果您愿意-比Cron允许的启动规则更灵活。无需sleep跳动

设置所需的时间比cron文件中的一行要多,但是如果您需要的内容比“每分钟”还多,那么值得付出努力。

SystemD计时器模型基本上是这样的:计时器是在计时器经过时启动服务单元的单元

因此,对于要调度的每个脚本/命令,必须有一个服务单元,然后有一个附加的计时器单元。一个计时器单元可以包含多个时间表,因此通常不需要多个计时器和一项服务。

这是一个简单的示例,每10秒记录一次“ Hello World”:

/etc/systemd/system/helloworld.service

[Unit]
Description=Say Hello
[Service]
ExecStart=/usr/bin/logger -i Hello World
Run Code Online (Sandbox Code Playgroud)

/etc/systemd/system/helloworld.timer

[Unit]
Description=Say Hello every 10 seconds
[Timer]
OnBootSec=10
OnUnitActiveSec=10
AccuracySec=1ms
[Install]
WantedBy=timers.target
Run Code Online (Sandbox Code Playgroud)

设置完这些单元后(/etc/systemd/system如上所述,对于系统范围的设置,或者~/.config/systemd/user对于用户特定的设置,为),您需要通过运行启用计时器(尽管不是服务)systemctl enable helloworld.timer。如果要立即启动计时器(而不是等待重新启动后再启动),请运行systemctl start helloworld.timer

[Timer]此处使用的部分字段如下:

  • OnBootSec -每次启动后数秒内启动服务。
  • OnUnitActiveSec-在上次启动服务后数秒钟内启动该服务。这就是导致计时器重复执行自身并像定时作业那样工作的原因。
  • AccuracySec-设置计时器的精度。计时器的准确性仅与该字段设置的一样,并且默认值为1分钟(模拟cron)。不要求最佳精度的主要原因是为了降低功耗-如果SystemD可以安排下一次运行与其他事件同时发生,则它需要较少地唤醒CPU。在1ms上面的例子并不理想-我通常设置精度1在我分分钟的计划作业(1秒),但是这将意味着,如果你看一下显示的“Hello World”消息的日志,你会看到,通常要迟到1秒。如果您对此表示满意,建议将精度设置为1秒或更长。

您可能已经注意到,该计时器不能很好地模仿Cron-从某种意义上说,该命令不是在每个挂钟周期的开始处启动的(即,它不是在时钟的第10秒开始,然后是20号,依此类推)。相反,只是在计时器过去时发生。如果系统在12:05:37引导,那么下一次命令运行将在12:05:47,然后在12:05:57,依此类推。如果您对实际的挂钟精度感兴趣,则可以想要替换OnBootSecOnUnitActiveSec字段,而是OnCalendar使用所需的时间表设置规则(据我所知,使用日历格式不能超过1秒)。上面的示例也可以写成:

OnCalendar=*-*-* *:*:00,10,20,30,40,50
Run Code Online (Sandbox Code Playgroud)

最后一点:您可能会猜到,该helloworld.timer单元将启动该helloworld.service单元,因为它们具有相同的名称(减去单元类型后缀)。这是默认设置,但是您可以通过设置Unit[Timer]部分的字段来覆盖它。

更多血腥细节可在以下网址找到:

  • 我经常在评论部分看到这样更好的答案。恕我直言,虽然 cron 一直是预定作业的主要内容,但这个答案应该是公认的,因为它不是睡眠的“黑客工作”,并且考虑到所需的间隔/频率,冒着执行长时间运行任务的并行化风险 (6认同)
  • 极好的答案,应该是选定的答案 (6认同)

小智 11

你可以查看我对这个类似问题的答案

基本上,我在那里添加了一个名为"runEvery.sh"的bash脚本,你可以每隔1分钟用cron运行一次,并将你希望运行的实际命令和你想要运行它的频率作为参数传递.

这样的事情

* * * * * ~/bin/runEvery.sh 5 myScript.sh


Pan*_*nde 9

Cron作业不能用于在几秒钟内安排作业.即你不能安排一个cron作业每5秒运行一次.另一种方法是编写一个使用sleep 5命令的shell脚本.

使用bash while循环创建一个shell脚本every-5-seconds.sh,如下所示.

$ cat every-5-seconds.sh
#!/bin/bash
while true
do
 /home/ramesh/backup.sh
 sleep 5
done
Run Code Online (Sandbox Code Playgroud)

现在,使用nohup如下所示在后台执行此shell脚本.即使您从会话中注销,这也将继续执行脚本.这将每5秒执行一次backup.sh shell脚本.

$ nohup ./every-5-seconds.sh &
Run Code Online (Sandbox Code Playgroud)

  • 时间会漂移.例如,如果`backup.sh`需要1.5秒才能运行,它将每6.5秒执行一次.有办法避免这种情况,例如`sleep $((5 - $(date +%s)%5))` (4认同)

小智 8

使用手表:

$ watch --interval .30 script_to_run_every_30_sec.sh
Run Code Online (Sandbox Code Playgroud)


小智 7

目前我正在使用以下方法。工作没有问题。

* * * * * /bin/bash -c ' for i in {1..X}; do YOUR_COMMANDS ; sleep Y ; done '
Run Code Online (Sandbox Code Playgroud)

如果你想每N秒运行一次,那么X将是60/NY将是N


Adi*_*iru 6

使用fcron(http://fcron.free.fr/) - 以秒为单位提供粒度,比cron(vixie-cron)更好,功能更丰富,也更稳定.我曾经制作过愚蠢的事情,例如在一台机器上运行非常愚蠢的设置运行大约60个PHP脚本,它仍然可以完成它的工作!

  • PHP开发者的自白;) (4认同)
  • 实际上,系统工程师的供词使 PHP 开发人员能够....:) (4认同)

lin*_*yfh 6

在dir /etc/cron.d/

新建一个文件 excute_per_30s

* * * * * yourusername  /bin/date >> /home/yourusername/temp/date.txt
* * * * * yourusername sleep 30; /bin/date >> /home/yourusername/temp/date.txt
Run Code Online (Sandbox Code Playgroud)

将每30秒运行一次cron