Script function which checks if itself is already running

Hi All,

I have a cron job set up which is set to run every 10 seconds.
What I need to do is have the script do a check to see if it is already running such that if it is running it wont fire up additional instances and processes according to its normal process.

For example if I have a script which checks to see if a file exists, and if exists, does a copy or move function of the file to another location, and then runs another process on it. If it is a large file that takes a long time to copy, and/or the other processes which I run on it takes a long time to complete, I don't want it to automatically fire up another instance of itself every 10 seconds.

So, lets say I have a script like the following: (and this isn't proper code, but just to illustrate the functions)

#!/bin/bash
#

1) Check to see if I am already running, and if so exit.

2) Check to see if file exists, and if it does process it.

EOF

What I am looking for is some way to determine if the script is running as in function 1.

Does anyone have any ideas how to achive this?

thanks,
landos

Create "lock file" when starting the script and remove it after script is done, for example:

if [ -f /var/tmp/script.lock ]; then
  echo "Already running. Exiting."
  exit 1
else
  touch /var/tmp/script.lock
fi

<main script code>

rm /var/tmp/script.lock
1 Like

Rather than use /var/tmp, the more common place to put lock files is in /var/run.

You also need a trap statement to remove the lock if somebody or something terminates the script.

LOCKFILE=/var/run/script.lock

trap "{ rm -f $LOCKFILE; exit 255; }" EXIT

if  [ -f $LOCKFILE ]
then
   echo "Already running. Exiting."
   exit 1
fi

touch $LOCKFILE

<main script code>

exit 0
1 Like

Ah, thanks..
The trap function was going to be my next question.

There are a couple of problems here. First, if the script is already running, the trap removes the lock file after reporting that the script is running.

And second, since the test for the lock file and the creation of the lock file is not a single atomic operation, there is a chance that the test by two are more invocations of this script could all succeed without knowing that another script had also succeeded.

The following script moves the trap on EXIT so that it only removes the lock file after this invocation of the script successfully creates the lock file. It also uses set -C to make the test for existence of the lock file and the creation of the lock file a single atomic operation. It also stores the PID of the lock holder in the lock file.

Unlike fpmurphy's script, this script does not remove the lock file if the script is terminated by a common signal. Note that the SIGKILL signal can't be caught and the lock file will never be removed in this case. If the script is terminated by a trapped signal, the exit code will be 128 plus the signal number; and if the script terminated normally, the exit code will be 0. (The script fpmurphy provided always exits with exit code 255 whether or not the script was terminated by a signal or completed successfully.) I did not install a trap on SIGALRM because this script uses sleep for demonstration purposes and some implementations of sleep use the SIGALRM signal. If you choose to catch other signals, you can find the signal number for them in /usr/include/signal.h (or something it #includes); the numbers for the signals used in this sample are supposed to be the same on all implementations that conform to the POSIX standards and the Single UNIX Specifications. If you want to remove the lock file in some or all of the signal catching cases, remove the trap "" EXIT from the trap for the desired signal(s):

#!/bin/ksh
IAm="${0##*/}"
LF="/var/run/$IAm.lock"

set -C
if  ! echo $$ > "$LF"
then
  printf "%s: Exitting, Already running as pid %s.\n" "$IAm" "$(cat "$LF")" >&2
  exit 1
fi
set +C

trap 'rm -f "$LF"' EXIT
trap 'echo "$IAm: Terminated by ABRT signal; $LF not removed." >&2
  trap "" EXIT
  exit 134' ABRT
trap 'echo "$IAm: Terminated by HUP signal; $LF not removed." >&2
  trap "" EXIT
  exit 129' HUP
trap 'echo "$IAm: Terminated by INT signal; $LF not removed." >&2
  trap "" EXIT
  exit 130' INT
trap 'echo "$IAm: Terminated by QUIT signal; $LF not removed." >&2
  trap "" EXIT
  exit 131' QUIT
trap 'echo "$IAm: Terminated by TERM signal; $LF not removed." >&2
  trap "" EXIT
  exit 143' TERM

echo 'other processing goes here; echo and sleep for demo'
echo "pid $$ sleeping"
sleep 300
1 Like