简体   繁体   中英

Schedule cron entries to run script only when not already running

I have one shell script in crontab which is executing jar file. Jar file is moving files from one server to another server. In peak hours it is taking more then 10 minutes(more then crontab entries).

How can I make sure that cron job will not execute process until last one is not completed ?

An easy way would be to have your Cron start a bashfile that checks if such a process exist.

cron:

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

(Make sure it has the correct user and is executable)

The pgrep command looks for a process with a the given name, and returns the processID when such a process is found.

#!/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

Inspired by F. Hauri's answer (which works fine btw), I came up with a shorter version :

 */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)

Crontab can't control script execution to make what you want, you must use something else. The simpler way I can think of doing it is by creating and monitoring a file containing the status of the executing task. First of all create a control file under the same directory as the bash script that calls Java doing: $echo 0 > javaisrun.txt

After this you can have the own script checking if Java is running or not and take the appropriated response doing something like:

#!/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

Script will read the 'javaisrun.txt' file, take its value and decide to go ahead with Java or not doing the update on the file while Java is executing and after execution.

I use sometime this kind of trick:

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

Not very sexy, but efficient.

I use an approach that is similar to Rodrigo's answer but also relegates semaphore cleanup to cron. Something like:

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

This way if somehow the job crashed or someone killed it, cron will take care of removing the lock file. It is not foolproof but has worked well for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM