每30秒运行一次cron

时间:2012-03-08 14:40:34

标签: ubuntu cron scheduled-tasks

好的,所以我有一个需要每隔30秒运行一次的cron。

这就是我所拥有的:

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

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

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

20 个答案:

答案 0 :(得分:616)

分钟说明符中有*/30 - 表示每分钟但步长为30(换句话说,每半小时一次)。由于cron不会达到亚分钟分辨率,因此您需要找到另一种方式。

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

* * * * * /path/to/executable param1 param2
* * * * * ( sleep 30 ; /path/to/executable param1 param2 )

两个 cron 作业每分钟都会运行,但后者会在执行作业的“肉”/path/to/executable之前等待半分钟。

答案 1 :(得分:58)

你做不到。 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'\''

答案 2 :(得分:35)

Cron的粒度是几分钟,不是设计为每隔x秒唤醒一次。在循环中运行重复任务,它应该做你需要的:

#!/bin/env bash
while [ true ]; do
 sleep 30
 # do what you need to here
done

答案 3 :(得分:22)

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

* * * * * /bin/bash -l -c "/path/to/executable; sleep 30 ; /path/to/executable"

所以在你的情况下:

* * * * * /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'\''"

答案 4 :(得分:11)

您可以查看我对this similar question

的回答

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

类似这样的事情

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

答案 5 :(得分: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

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

$ nohup ./every-5-seconds.sh &

答案 6 :(得分:7)

使用手表:

$ watch --interval .30 script_to_run_every_30_sec.sh

答案 7 :(得分:6)

在目录/etc/cron.d/

新建一个文件excute_per_30s

* * * * * yourusername  /bin/date >> /home/yourusername/temp/date.txt
* * * * * yourusername sleep 30; /bin/date >> /home/yourusername/temp/date.txt

将每30秒运行一次cron

答案 8 :(得分:6)

如果您正在运行带有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

/etc/systemd/system/helloworld.timer

[Unit]
Description=Say Hello every 10 seconds
[Timer]
OnBootSec=10
OnUnitActiveSec=10
AccuracySec=1ms
[Install]
WantedBy=timers.target

设置完这些单位后(如上所述,在/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

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

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

答案 9 :(得分:5)

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

答案 10 :(得分:4)

Crontab作业可用于以分钟/小时/天为单位安排作业,但不能以秒为单位。替代方案:

创建一个每30秒执行一次的脚本:

#!/bin/bash
# 30sec.sh

for COUNT in `seq 29` ; do
  cp /application/tmp/* /home/test
  sleep 30
done

使用crontab -e和crontab执行此脚本:

* * * * * /home/test/30sec.sh > /dev/null

答案 11 :(得分:1)

感谢所有好的答案。为了简单起见,我喜欢混合解决方案,使用crontab上的控件和脚本上的时分。所以这就是我每隔20秒(每分钟三次)运行一个脚本所做的。 Crontab行:

 * * * * 1-6 ./a/b/checkAgendaScript >> /home/a/b/cronlogs/checkAgenda.log

脚本:

cd /home/a/b/checkAgenda

java -jar checkAgenda.jar
sleep 20
java -jar checkAgenda.jar 
sleep 20
java -jar checkAgenda.jar 

答案 12 :(得分:0)

我只是有类似的任务要做,并使用以下方法:

nohup watch -n30 "kill -3 NODE_PID" &

我需要每隔30秒定期杀死-3(以获取程序的堆栈跟踪)几个小时。

nohup ... & 

这是为了确保如果我松开外壳(网络问题,Windows崩溃等等),我不会丢失手表的执行情况。

答案 13 :(得分:0)

编写一个shell脚本 创建.sh文件

每30秒一次纳米。sh

并编写脚本

#!/bin/bash
For  (( i=1; i <= 2; i++ ))
do
    write Command here
    sleep 30
done

然后为此脚本设置cron crontab -e

(* * * * * /home/username/every30second.sh)

此cron调用.sh文件每1分钟运行一次,.sh文件命令中的.sh文件每1分钟运行2次

如果要运行脚本5秒钟,则将30替换为5,然后更改循环,如下所示:For (( i=1; i <= 12; i++ ))

当您选择任何秒数时,请计算60 /秒并写入For循环

答案 14 :(得分:0)

当前,我正在使用以下方法。没问题。

* * * * * /bin/bash -c ' for i in {1..X}; do YOUR_COMMANDS ; sleep Y ; done '

如果您想每隔 N 秒运行一次,则 X 将为 60 / N ,而 Y 将为 N

谢谢。

答案 15 :(得分:0)

看看frequent-cron-它很旧但是很稳定,您可以降低到微秒。在这个时候,我唯一要反对的是,我仍在尝试如何在init.d之外安装它,但作为本机systemd服务,但是肯定可以在Ubuntu 18之前运行仍然可以使用init.d进行操作(距离可能在以后的版本中有所不同)。它具有附加的优势(?),确保除非先前的脚本完成,否则不会生成该PHP脚本的另一个实例,从而减少了潜在的内存泄漏问题。

答案 16 :(得分:0)

您可以将该脚本作为服务运行,每30秒重新启动

注册服务

app.use('/api', expressJwt({ secret: config.secret }).unless( 
    { path: ['']
    {url:'/api/imageAPI/', methods: ['GET']},]
}

app.use('/api/imageAPI/Images/', 
express.static(path.join(__dirname,'../../Images/')));

在下面的命令中粘贴

sudo vim /etc/systemd/system/YOUR_SERVICE_NAME.service

重新加载服务

Description=GIVE_YOUR_SERVICE_A_DESCRIPTION

Wants=network.target
After=syslog.target network-online.target

[Service]
Type=simple
ExecStart=YOUR_COMMAND_HERE
Restart=always
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

启用服务

sudo systemctl daemon-reload

启动服务

sudo systemctl enable YOUR_SERVICE_NAME

检查您的服务状态

sudo systemctl start YOUR_SERVICE_NAME

答案 17 :(得分:-1)

为什么不仅仅添加两个连续的命令条目,它们都在不同的秒开始?

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

答案 18 :(得分:-1)

通过反复试验,我找到了正确的表达式:*/30 * * ? * * * 这转化为每 30 秒一次。 参考:https://www.freeformatter.com/cron-expression-generator-quartz.html 他们提供了每秒运行的表达式: * * * ? * * * */x 用于以每 x 个单位运行。我在分钟的位置和中提琴上尝试过。我相信其他人已经发现了这一点,但我想分享我的尤里卡时刻! :D

答案 19 :(得分:-2)

在shell循环中运行,例如:

*.php