Exclusive locks in Bourne shell scripts

Chris writes:

Been writing some stuff in shell that needs to be able to ensure it doesn’t start itself twice, so a bit of Googling for exclusive locks in shell scripts brought me to this page on “advanced shell scripting” which had something that looked good.

Problem is that when you put it into a script you’ll find it doesn’t actually work because of some trivial coding issues.

So here’s the fixed version of that function..

[…long code segment elided…]

Really I am appalled at the lack of uptake of a really neat hack that totally circumvents this problem; I know what the problem is – the problem is that people use the term “lockfiles”.

That’s the problem.

Here’s the hint: mkdir(2) is guaranteed atomic (and, I believe, complete) on local filesystems; so long as the parent directory is world-writable and has a stickybit to prevent people playing fast and loose with the locks, a very effective advisory lock in a shellscript can be implemented via:

 LOCKDIR=/tmp/.prognamelock getLock() {  if mkdir -m 0755 $LOCKDIR  then  : we got it; some nice syntactic sugar might include  date > $LOCKDIR/date  echo $$ > $LOCKDIR/pid  else  : we didn’t; debug, poll, or wait, or whatever  fi } freeLock() {  if rm -r $LOCKDIR  then  : ok  else  : wtf, barf, diag, etc  fi } 

I have no idea why this trick has not caught on for coarse shell-script locks. Its portable, robust, pretty good over NFS even, and it beats the hell out of playing sillybuggers with “ln”, subshells and other toys; you might want to add a stale-lock test, but that’s about all.

Comments

2 responses to “Exclusive locks in Bourne shell scripts”

  1. Chris Samuel
    re: Exclusive locks in Bourne shell scripts

    Yes, that does work, but these were for UPS shutdown scripts where I wanted to record the PIDs as well and where cleanups are, well, not going to happen! (Unless the power comes back and then we can kill one or both of the shutdown scripts, depending on which UPS gets power)

    The article I linked to does include a mkdir version which (just link ln used in my version) is atomic, but I would then have had to record the PID somewhere in that direcotry which, in turn, would need atomic locking, so I decided I might as well just do it using this method which gave me a PID file for free..

  2. Stephen Usher
    re: Exclusive locks in Bourne shell scripts

    I guess using a lockdir in a ram disk wouldn’t help as an automatic clean-up if you wanted things recorded.

    As for lockdirs in general, they’re the best method, even if you don’t store anything in them.

    The best way I’ve found to make sure that locks aren’t stale is to record not only the PID (as another process may have started subsiquently with that PID) but the time the lock was created so that you can set a timeout in your script for automatic cleansing.

Leave a Reply

Your email address will not be published. Required fields are marked *