Greg Ubben sent this idea.
A lockfile can be used if a particular program might be run more than once at the same time - and you need to be sure that only one instance of the program can do something (like modify some file, access a printer, etc.). Let's say you have a script called edmaster; it edits a master configuration file named config. To be sure that two users can't modify the config file at the same time, the first edmaster would check whether the lockfile exists. If the lockfile doesn't exist, edmaster will create it and modify the config file. When it's done editing, it removes the lockfile. If someone tries to run a second edmaster process, it will see the lockfile from the first edmaster, wait and check every few seconds to see if the lockfile is gone. Once the first edmaster removes the lockfile, the second edmaster can create the lockfile and do its editing of config.
# set name of this program's lockfile: myname=`basename $0` LOCKFILE=/tmp/lock.$myname ... # Loop until we get a lock: until (umask 222; echo $$ >$LOCKFILE) 2>/dev/null # test & set do # Optional message - show lockfile owner and creation time: set x `ls -l $LOCKFILE` echo "Waiting for user $4 (working since $7 $8 $9)..." sleep 5 done # Do whatever we need exclusive access to do... ... rm -f $LOCKFILE # unlock
So if another user tried to run edconfig, and jpeek had run edconfig first, she might see:
edconfigWaiting for user jpeek (working since Aug 23 14:05)... ...a 5-second pause Waiting for user jpeek (working since Aug 23 14:05)... another 5-second pause... ...then jpeek finishes and she can edit the file.
How does it work?
Almost all of the action is in the first line of the loop.
A umask of 222 creates files that are read-only
Because the umask 222 command is run in a
it only affects the lockfile that's created in the subshell at the top
of the loop.
The rest of the shell script keeps its normal umask.
If the lockfile already exists (because another process has created it),
the loop executes
sleep 5; five seconds later, it tries to create
If the lockfile exists, it will be read-only - so, the command
echo $$ >$LOCKFILE will return a nonzero status.
A nonzero status is what keeps an
Once the other process (which has the lock) removes the lockfile,
the echo command in the subshell will write the shell's process
ID number into the lockfile and the until loop will terminate.
But, if the lockfile is read-only, how can it ever be created? That's the other interesting part of this technique. The umask only applies to the file as it's created; if the file doesn't exist, the umask doesn't apply to it (yet) and the file can be created. In fact, you can create a file with mode 000 by typing:
(umask 666; echo hi > afile)$
ls -l afile---------- 1 jpeek wheel 3 Aug 23 14:08 afile