PDA

View Full Version : where to set a if condition for a crontab job to execute



oj43085
03-Jun-2014, 11:07
Hi,

Want to know where can I set an if condition to check for a currently running process, if that process is running, then do not execute. Else, execute. Can I set that condition inside the script itself?

If the script is called my_script.sh, in the start of the script, check to see if a PID for this scheduled script is already running, if so...do not execute. ( I want the previous one to finish)

like

CHECK=$(pgrep my_script.sh)
if [[ -z "$CHECK"]] then ;
my_script.sh starts here

mikewillis
03-Jun-2014, 11:45
Want to know where can I set an if condition to check for a currently running process, if that process is running, then do not execute. Else, execute. Can I set that condition inside the script itself?

Yes, you can and should set that in the script. There's various ways to do it. One of the Google search terms will will bring up lots of useful information on this is "bash script lock file". For example:

http://mywiki.wooledge.org/BashFAQ/045
http://wiki.bash-hackers.org/howto/mutex

Note that if you use a lock file/directory you must remember to ensure the script removes it when it exits even if it doesn't exit cleanly. Both the above links show how to do that using trap.

I'm assuming you're doing it in bash. You don't say, but the bit of example code you posted looks like part of a bash script.

ab
03-Jun-2014, 12:16
On 06/03/2014 04:14 AM, oj43085 wrote:
>
> Want to know where can I set an if condition to check for a currently
> running process, if that process is running, then do not execute. Else,
> execute. Can I set that condition inside the script itself?

I my be confused, but it seems like you have answered your own question
right here:

> If the script is called my_script.sh, in the start of the script, check
> to see if a PID for this scheduled script is already running, if so...do
> not execute. ( I want the previous one to finish)

Yes, this can potentially work.

> like
>
> CHECK=$(pgrep my_script.sh)
> if [[ -z "$CHECK"]] then ;
> -my_script.sh starts here-

I've done this a bit lately and opted to use the flock function to prevent
problems. From what I've read, it's the only perfect way to handle all
possibilities preventing simultaneous execution of the script as well as
perfect cleanup regardless of what happens to the process while running:

Code:
--------------------
flock -n /tmp/mail-forwarder.lockfile -c '/usr/bin/mail-forwarder'
>/dev/null 2>&1
--------------------

--
Good luck.

If you find this post helpful and are logged into the web interface,
show your appreciation and click on the star below...

oj43085
09-Jun-2014, 08:00
Yes, you can and should set that in the script. There's various ways to do it. One of the Google search terms will will bring up lots of useful information on this is "bash script lock file". For example:

http://mywiki.wooledge.org/BashFAQ/045
http://wiki.bash-hackers.org/howto/mutex

Note that if you use a lock file/directory you must remember to ensure the script removes it when it exits even if it doesn't exit cleanly. Both the above links show how to do that using trap.

I'm assuming you're doing it in bash. You don't say, but the bit of example code you posted looks like part of a bash script.

Hi,

I am indeed using bash, sorry for not clarifying.

Currently I am calling the backup jobs from crontab directly.

So, If I want to use the flock from your link, refering to this:

exec 9>/path/to/lock/file
if ! flock -n 9 ; then
echo "another instance is running";
exit 1
fi
# this now runs under the lock until 9 is closed (it will be closed automatically when the script ends)

If i want to include this file lock into my crontab scheduled tasks, then should crontab call another .sh called, for example, execute_task1.sh and then the contents of execute_task1.sh can be:

exec 9>/path/to/lock/file
if ! flock -n 9 ; then
echo "another instance is running";
exit 1
fi
else
/rsync_jobs/job1.sh
# this now runs under the lock until 9 is closed (it will be closed automatically when the script ends)

mikewillis
09-Jun-2014, 10:14
If i want to include this file lock into my crontab scheduled tasks, then should crontab call another .sh called, for example, execute_task1.sh and then the contents of execute_task1.sh can be:

exec 9>/path/to/lock/file
if ! flock -n 9 ; then
echo "another instance is running";
exit 1
fi
else
/rsync_jobs/job1.sh
# this now runs under the lock until 9 is closed (it will be closed automatically when the script ends)
What you post would work, assuming nothing else is going to call job1.sh. But unless execute_task1.sh is going to more than just job1.sh then put the locking stuff in job1.sh and call job1.sh from crontab.

It might help if you made your self a simple script to see how the locking works. E.g.

#!/bin/bash

exec 9>/tmp/$(basename $0)_lock
if ! flock -n 9 ; then
echo "another instance is running";
exit 1
fi

sleep 600
Run that, then try running another instance of it.