Using lock file to prevent duplicate scripts from running?

978 views
Skip to first unread message

Michael Wang

unread,
Jan 29, 1999, 3:00:00 AM1/29/99
to
Can I use lock file to prevent duplicate copies of a script from
running? If two script starts at the *EXACTLY* the same time, they will
be both running. Is this right? What is the probability? What is
the better solution? Thanks.

Very simple script to demonstrate the concept:

if [[ -f /a/file ]]
then echo "a copy of script is running."
else touch /a/file
fi
trap 'rm /a/file; exit' 0 1 2 3 15
--
unix programs: niftp (non-interactive recursive ftp), hide (hide command args),
submit (replace nohup), etc from ftp://ftp.mindspring.com/users/mwang/unix-prog
Michael Wang, mw...@ml.com, Merrill Lynch, World Financial Center, 212-449-4414

Kurt J. Lanza

unread,
Jan 29, 1999, 3:00:00 AM1/29/99
to
Michael Wang wrote:
>
> Can I use lock file to prevent duplicate copies of a script from
> running? If two script starts at the *EXACTLY* the same time, they will
> be both running. Is this right? What is the probability? What is
> the better solution? Thanks.
>
> Very simple script to demonstrate the concept:
>
> if [[ -f /a/file ]]
> then echo "a copy of script is running."
> else touch /a/file
> fi
> trap 'rm /a/file; exit' 0 1 2 3 15

I normally use a directory as a lock file -- since creating a directory
is usually an atomic operation. In Bourne shell:

mkdir /tmp/locka 2>/dev/null || {
echo Already running
exit
}
trap "rmdir /tmp/lock" 0
... # Do your thing.

Even if you do your damndest to start two or more at the same time,
only one will succeed.

Dan Mercer

unread,
Jan 29, 1999, 3:00:00 AM1/29/99
to
In article <78sltc$pje$1...@news.ml.com>,

mw...@tech.cicg.ml.com (Michael Wang) writes:
> Can I use lock file to prevent duplicate copies of a script from
> running? If two script starts at the *EXACTLY* the same time, they will
> be both running. Is this right? What is the probability? What is
> the better solution? Thanks.
>
> Very simple script to demonstrate the concept:
>
> if [[ -f /a/file ]]
> then echo "a copy of script is running."
> else touch /a/file
> fi
> trap 'rm /a/file; exit' 0 1 2 3 15

You have a potential race condition. In the time between:

if [[ -f /a/file ]]

and touch /a/file

there is time for another script to:

if [[ -f /a/file ]]

You need an atomic operation that will return an error and set the
semaphore simultaneously. The mkdir command does nicely.
The problem with this, of course, is ensuring that the semaphore
is rmdir'd successfully. Be sure to set plenty of traps:

# block all signals
SIGS=$(echo "for (i=0;i<35;i++)i"|bc)
trap : $SIGS
SEMAPHORE=/var/spool/semaphores/${0##*/}
if mkdir $SEMAPHORE
then
# go to town
trap "[[ -d $SEMAPHORE ]] && rmdir $SEMAPHORE" $SIGS
else


echo "a copy of script is running."

fi

That's probably overkill on the traps and you need to play
around to see what the side effects are (set the trap in a stub
script, send kill).

Note, by trapping on 0 you don't need to place another
rmdir in your code.


Dan Mercer

dame...@uswest.net


Opinions expressed herein are my own and may not represent those of my employer.


james.m....@gmail.com

unread,
Aug 15, 2012, 10:38:15 AM8/15/12
to
On Friday, January 29, 1999 3:00:00 AM UTC-5, Dan Mercer wrote:
> In article <78sltc$pje$1...@news.ml.com>,
> mw...@tech.cicg.ml.com (Michael Wang) writes:
> > Can I use lock file to prevent duplicate copies of a script from
> > running? If two script starts at the *EXACTLY* the same time, they will
> > be both running. Is this right? What is the probability? What is
> > the better solution? Thanks.
> >
> > Very simple script to demonstrate the concept:
> >
> > if [[ -f /a/file ]]
> > then echo "a copy of script is running."
> > else touch /a/file
> > fi
> > trap 'rm /a/file; exit' 0 1 2 3 15
>
> You have a potential race condition. In the time between:
>
> if [[ -f /a/file ]]
>
> and touch /a/file
>
> there is time for another script to:
>
> if [[ -f /a/file ]]
>
> You need an atomic operation that will return an error and set the
> semaphore simultaneously. The mkdir command does nicely.
> The problem with this, of course, is ensuring that the semaphore
> is rmdir'd successfully. Be sure to set plenty of traps:
>
> # block all signals
> SIGS=$(echo "for (i=0;i<35;i++)i"|bc)
This can be more clearly accomplished by:
SIGS=$(seq 0 34) in dash
and most efficiently by:
SIGS=$(echo {0..34})
if you are using bash or zsh.
Reply all
Reply to author
Forward
0 new messages