如果条件为真,则让 cron 任务休眠 5 分钟

如果条件为真,则让 cron 任务休眠 5 分钟

我有一个脚本设置为每分钟运行一次。但是在我们提到的脚本中,如果条件为真,则脚本必须休眠 5 分钟。这会如何影响 crontab?脚本会处于休眠模式 5 分钟,还是会像在 crontab 中设置的那样每 1 分钟再次运行一次?

答案1

您有两种方法可以实现这一点。通常,cron 并不关心该作业的上一个实例是否仍在运行。

选项1:

在脚本开头写入一个锁定文件,并在脚本完成后将其删除。然后在脚本开头检查该文件是否存在,如果存在,则脚本不执行任何操作而结束。例如,如下所示:

# if the file exists (`-e`) end the script:
[ -e "/var/lock/myscript.pid" ] && exit

# if not create the file:
touch /var/lock/myscript.pid

...
# do whatever the script does.
# if condition
sleep 300 # wait 5 min
...

# remove the file when the script finishes:
rm /var/lock/myscript.pid

选项 2:

还有一个实用程序可以实现这一点。它被称为run-one。摘自手册页:

run-one - 每次只运行某个命令和一组唯一参数的一个实例(例如,对于 cronjobs 有用)

cronjob 可能看起来像这样:

* * * * *   /usr/bin/run-one /path/to/myscript

答案2

我做过类似的事情 - 如果发生某些事情,我会暂停脚本,但我没有从 cron 运行它。相反,我有一个会不断重新运行的 shell 脚本。就我而言,我检查了平均负载,如果“太高”,我会暂停一分钟。如果一切正常,我会做我需要做的事情,然后暂停更短的时间。

这也具有双重优点,即只会运行一个脚本,并且您还可以每分钟以上重新运行它,这是最低 cron 频率。

#!/bin/bash

i_should_sleep() {
  if [ *condition* ]
  then
    return 0
  else
    return 1
  fi
}

if i_should_sleep; then
    sleep 300
    exec $0 $@
fi

nice COMMAND # run the action we really want to do

sleep 60  # or less than a minute, to run more often

exec $0 $@

要启动它,您需要创建一个 Upstart 或 init.d 作业,或类似的东西。

答案3

使用 crontab,您无法做到这一点,但您可以通过对脚本进行一些扩展来实现这一点。我正在考虑以下伪代码:

#!/bin/bash
if ...temporary_file_exists
then
  if ...tmp_is_older_as_5_minute...
  then
     delete tmp
  else
     exit
  fi
fi

...
if "${condition}"
then
  touch $temporary_file
  exit
fi

...normal behavior of your script...

它能做什么? cron 脚本的主要问题是,您无法轻松地在运行之间保留持久内存。您需要始终使用临时方法来做到这一点。在 unix 脚本世界中,临时文件是解决此问题的非常常见的解决方案,您可以使用临时文件的存在(和更改时间)来了解实际情况。

相关内容