[NBLUG/talk] Mutual exclusion in shell scripts?

Lincoln Peters sampln at sbcglobal.net
Sun Jan 21 19:02:11 PST 2007

On Saturday 20 January 2007 18:38, Eric Eisenhart wrote:
> > Except I'm trying to use this as a manual filter in KMail.
> lockfile is a separate program that's packaged with procmail because
> procmail uses it.  "man lockfile".  Don't need to use procmail to use
> lockfile.
> The lockfile-using version of your program is:
>   lockfile /tmp/filter.lock
>   sa-learn $1 --no-sync
>   rm -f /tmp/filter.lock

OK, now I get it.

> (well, that's the default 8 second sleep; read the manpage if it must be
> 10. There's also options for breaking a lock after a timeout, locking
> mailboxes, changing to a conditional "if lockfile ...", etc...)

The 10-second timer was arbitrary, and wasn't even what I was using (I used it 
in the e-mail because it was simpler than what I had done).  I had actually 
rigged the script to choose a delay based on how many instances of itself 
were already queued up.  Specifically:

export N=`pidof -x filter.sh | wc -w`
while ...
    sleep $N

I figured that this approach would reduce the likelihood of a bunch of scripts 
waking up all at the same time to see if they can run yet, only to go back to 
sleep, and hammering the CPU in the process.  But I make no representations 
as to the effectiveness of this approach.

In case anyone's wondering, when I applied your earlier suggestion about 
combining the check and set into a single atomic operation, everything seemed 
to work.  Because of the somewhat dynamic sleep duration I had set up, the 
queues sometimes take a while to empty, but since the script tends to be 
called many times in rapid succession, with a long gap between one set of 
calls and the next, this doesn't seem to be an issue.

> Unless you use something like lockfile (or a snippet of perl code...), all
> the solutions for locking in a shell script will be ugly.  No direct access
> to open with O_EXCL.  I think you could do what open(2) suggests in shell,
> but it's even uglier, especially since it's a technique looking for a do
> while loop, not a while loop:
>   rm -f /tmp/filter.lock.$$
>   touch /tmp/filter.lock.$$
>   ln /tmp/filter.lock.$$ /tmp/filter.lock
>   until [ `stat -t /tmp/filter.lock.$$ | cut -d' ' -f9` == 2 ] ; do
>     sleep 10
>     ln /tmp/filter.lock.$$ /tmp/filter.lock
>   done
>   sa-learn $1 --no-sync
>   rm -f /tmp/filter.lock /tmp/filter.lock.$$

Yes, that's even uglier!

Lincoln Peters		<sampln at sbcglobal.net>

The hearing ear is always found close to the speaking tongue, a custom
whereof the memory of man runneth not howsomever to the contrary, nohow.

More information about the talk mailing list