我有一个脚本设置为每分钟运行一次。但是在我们提到的脚本中,如果条件为真,则脚本必须休眠 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 脚本世界中,临时文件是解决此问题的非常常见的解决方案,您可以使用临时文件的存在(和更改时间)来了解实际情况。