我有以下关于 cron 作业的一般性问题。
假设我的 中有以下内容crontab
:
* 10 * * * * someScript.sh
* 11 * * * * someScript2.sh
30 11 */2 * * someScript3.sh <-- Takes a long time let's say 36 hours.
* 12 * * * someScript4.sh
它是否足够聪明,可以在适当的时间运行剩余的作业?例如,长脚本不需要终止?
另外,如果最初的长脚本仍在运行并且它再次被 cron 调用,会发生什么情况?
答案1
答案2
不知道你所说的适当时间是什么意思。 Cron 将在预定的时间启动作业。它不检查其他计划作业或作业的其他实例。
因此,您定义的任何有效作业都将在定义的时间开始。任何运行时间超过定义的时间间隔的作业都将启动多次。编写该作业的人有责任防止它在需要时实际运行多次。例如通过检查锁定文件或 PID 文件或其他东西。
可以并行运行的进程数量有明显的限制,但这些限制不是特定于 cron 的。
答案3
除了其他答案之外,特别是 @soulcake 发布的链接:如果您以太短的时间间隔安排一个长时间运行的命令,cron 会很乐意在第一个命令完成之前执行第二个命令(除非命令中实现了某种互斥体) 。
这通常会进一步减慢原始命令的速度,导致在前一个实例完成之前运行另一个实例,等等。或者由于其他原因,这可能是不受欢迎的。
预防的一般方法是使用防护条件运行命令,以确保先前的命令没有运行。例如:
10 * * * * pgrep my_slow_command >/dev/null || /usr/local/bin/my_slow_command
确保 pgrep 在运行时与命令的名称匹配,例如 python 脚本将 python 作为可执行文件的名称,这可能不够具体,您还必须与 python 的脚本名称进行匹配。
10 * * * * pgrep -f my_script.py || /usr/local/bin/my_script.py
(不过,不带“-f”选项的 pgrep 与 bash 脚本名称匹配)
如果由于某种原因无法使用 pgrep:
10 * * * * ps ax | grep [m]y_command || /usr/local/bin/my_command
括号用于避免匹配 grep 命令本身。
答案4
我用flock
。
* * * * * exec flock --nonblock .ws_client.lock -c ws_client.py >& /tmp/ws_client.out