仅在尚未 运行ning 时将 cron 条目安排到 运行 脚本

Schedule cron entries to run script only when not already running

我在 crontab 中有一个 shell 脚本正在执行 jar 文件。 Jar 文件将文件从一台服务器移动到另一台服务器。在高峰时段,它需要超过 10 分钟(超过 crontab 个条目)。

如何确保 cron 作业在最后一个作业未完成之前不会执行进程?

crontab 无法控制脚本执行来做出你想要的,你必须使用其他东西。我能想到的更简单的方法是创建和监视一个包含执行任务状态的文件。首先在与调用 Java 的 bash 脚本相同的目录下创建一个控制文件: $echo 0 > javaisrun.txt

在此之后,您可以让自己的脚本检查 Java 是否为 运行 并采取适当的响应来执行以下操作:

#!/bin/bash

A=$(cat javaisrun.txt)

if [ $A = 1 ]; then
echo Java is running already
else
echo Not Running, start Java
echo 1 > javaisrun.txt
java -jar temp3.jar
echo Java job is done, restoring state file
echo 0 > javaisrun.txt
fi

脚本将读取 'javaisrun.txt' 文件,取其值并决定继续 Java 或在 Java 执行期间和执行后不对文件进行更新。

我使用的方法类似于 Rodrigo 的回答,但也将信号量清理委托给 cron。类似于:

* * * * *  cd workdir; S=<a lockfile name>; touch $S; myjob jobparams; rm $S

这样,如果作业因某种原因崩溃或有人杀死它,cron 将负责删除锁定文件。它并非万无一失,但对我来说效果很好。

一个简单的方法是让您的 Cron 启动一个 bashfile 来检查是否存在这样的进程。

定时任务:

 */10 * * * * /path/to/bashscript.sh

(确保它有正确的用户并且是可执行的)

pgrep 命令查找具有给定名称的进程,returns 找到此类进程时的 processID。

#!/bin/bash
# bashscript.sh    

pID=$(pgrep -n "yourjarfile") 

# Check if jarfile is running
if $pID > /dev/null
then       
    #log something to syslog 
    logger  $pID "already running. not restarting." 
else
    # start jar file 
    /usr/bin/java -jar /path/to/yourjarfile.jar
fi

--编辑--

受 F. Hauri 的回答(顺便说一句效果很好)的启发,我想出了一个较短的版本:

 */10 * * * *  pgrep -n "yourjarfile." || /usr/bin/java -jar /path/to/yourjarfile.jar

你可以直接在cron入口使用穷人的锁文件,比如:

* * * * * LOCKFILE=whatever; [ ! -f $LOCKFILE ] && (touch $LOCKFILE && /path/to/java javaargs ; rm $LOCKFILE)

我有时会用到这种技巧:

*/10 * * * * ps -C javaws www| grep -q mytool.jar || javaws ... mytool.jar

不是很性感,但很有效率。