This post is old (2011), there are many better ways to do this.
See https://www.unix.com/man-page/linux/1/flock/ for one example.
Also pgrep and lsof examples here:
https://www.baeldung.com/linux/bash-ensure-instance-running
—
Wrote this script recently – I had written a simple shell script that updated an HTML page with its output, then realised it would be all too easy for simultaneous writes to clobber the file.
This kind of concurrency can & should really be solved properly by using a database obviously, but it got me thinking and playing around and I ended up with the below – it’s clearly very “happy path” with loads of room for improvements – please feel free to suggest some or add to it 🙂
#!/bin/bash
#
# Example script that uses lock files to avoid concurrent writes
# TODO: loads more validation and error handling!
#
# www.DonaldSimpson.co.uk
# 25th May 2011
setup_lockfile(){
# set name of this program’s lockfile:
MY_NAME=`basename $0`
LOCKFILE=/tmp/lock.${MY_NAME}.$$
# MAX_AGE is how long to wait until we assume a lock file is defunct
# scary stuff, with loads of scope for improvement…
# could use fuser and see if there is a process attached/not?
# maybe check with lsof? or just bail out?
MAX_AGE=5
echo “My lockfile name is ${LOCKFILE}”
sleep 1
}
check_lock(){
# Check for an existing lock file
while [ -f /tmp/lock.${MY_NAME}* ]
do
# A lock file is present
if [[ `find /tmp/lock.* -mmin +${MAX_AGE}` > “0” ]]; then
echo “WARNING: found and removing old lock file…`ls /tmp/lock.${MY_NAME}*`”
rm -f /tmp/lock.${MY_NAME}*
else
echo “A recent lock file already exists : `ls /tmp/lock.${MY_NAME}* | awk -F. {‘print $2″.”$3″, with PID: ” $4’}`”
echo “Will wait until the lock file is over ${MAX_AGE} minutes old then remove it…”
fi
sleep 5
done
}
create_lock(){
# ok to carry on… create a lock file – quickly 😉
touch ${LOCKFILE}
# check we managed to make it ok…
if [ ! -f ${LOCKFILE} ]; then
echo “Unable to create lockfile ${LOCKFILE}!”
exit 1
fi
echo “Created lockfile ${LOCKFILE}”
}
cleanup_lock(){
echo “Cleaning up… ”
rm -f ${LOCKFILE}
if [ -f ${LOCKFILE} ]; then
echo “Unable to delete lockfile ${LOCKFILE}!”
exit 1
fi
echo “Ok, lock file ${LOCKFILE} removed.”
}
setup_lockfile
check_lock
create_lock
# Any calls to exit() from here on should first call cleaup_lock
# Do main processing tasks here…
sleep 20
# All Done.
cleanup_lock
Discover more from Don's Blog
Subscribe to get the latest posts sent to your email.
WordPress trashed my indenting 🙁
And wrapped the lines too – here’s a clean version:
http://dontemp.donwp.freemyip.com:9000/userContent/newlock.sh
Actually, there are much nicer/simpler ways to implement the locking/waiting part of the above – something like flock (http://linux.about.com/library/cmd/blcmdl2_flock.htm), or the inotify commands could also be used – http://linux.die.net/man/1/inotifywait – to wait/watch for a lock. This page has some details on that: http://www.server-world.info/en/note?os=CentOS_6&p=inotify
This script was exactly what I needed when I was facing concurrency issues with writing to files in my Bash script. I was struggling with the risk of simultaneous writes clobbering the file, and this lockfile approach made it so much easier to handle. I did notice a few things could be improved, but it definitely gave me a solid base to work from.
Also, for anyone dealing with setting up Miniconda on Ubuntu 24.04, I found a great guide on how to [install miniconda ubuntu 24.04](https://docs.vultr.com/how-to-install-miniconda-on-ubuntu-24-28), which helped me solve a few setup issues I was dealing with.
Thanks for sharing this! It’s been a huge help, and I love how simple and effective the lockfile approach is. 😊