Using lock files in a bash shell script

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

Updated to latest Jenkins

Finally got around to trying out “Jenkins”, the latest incarnation of the forked “Hudson” project, and one of my favourite tools. Jenkins looks and works very much like the latest Hudson, but as it had been a while since I last browsed the plugins there were a few nice additions.

When I first started using Hudson there were about 5 basic plugins, and the amount and quality available in the latest version of Jenkins is really impressive – obviously it depends on what sort of tasks and tools you use, but there’s something for everyone – here is a list of the ones I found most useful and interesting:

Hudson Google Calendar plugin

This plugin publishes the job status to Google Calendar.

I think this has maybe been around for a while but I hadn’t used it before – it simply publishes build info to your Google Calendar, which can be a nice way to view a summary for some jobs.

Hudson iPhoneView plugin

This plugin allows you to view the status of your jobs via iPhone or iPod touch.

Haven’t tried this out yet but it’s on my todo list!

Hudson SCP publisher plugin

This plugin uploads build artifacts to repository sites using SCP (SSH) protocol.

This is a plugin for something I would usually script in Ant or shell script – will try this instead as it should make things simpler and cleaner.

Security Realm with no CAPTCHA

Brilliant – the Hudson/Jenkins Captcha can be really tough, being able to remove it is very nice.

Jenkins SSH plugin

This plugin executes shell commands remotely using SSH protocol.

Much like the SVN plugins, this is something I would normally write by hand – this plugin lets you define hosts (with user and passwords) then select them and the task you want to run from within a job, very handy and again much less clutter – another essential.

Startup Trigger

This plugin allows you to trigger a Jenkins build when Jenkins first starts up.

Simple but useful – I have used this one on a server that is restarted nightly; it kicks off some housekeeping jobs and mails me the outcome every morning.

Hudson Subversion Tagging Plugin

This plugin automatically performs Subversion tagging (or copy) on successful build.

Another useful Subversion integration plugin – I have recently been using this in conjunction with another plugin that dynamically generates a drop-down of all available tags in a given SVN location at build time. This allows users to select the tag they want to deploy, a very powerful and useful combination.

Cheers,

Don