Serialise Asynchronous Shell Scripts
You know that your shell script will break if more than one copy is running in the system. You also know that your script will be launched via a scheduler and you do not have control on when the job will be run. In such situation, you may want to have some form of locking mechanism feature in your script to ensure serialisation. First, your script has to start with acquiring a lock before doing any work. If not, it will have to go into a spin and check periodically to see whether such lock is still available, else exit if such lock cannot be acquired within a certain period. Removal of lockfile is part of the cleanup process when the script terminates.
Here is my sample template to implement what I described above. Hope it can help you to serialise your asynchronous jobs.
#! /bin/ksh trap "lock_release" 0 1 2 3 5 9 15 LOCK_FILE="${TMPDIR:-/tmp}/lockfile-${0##*/}" too_old=86400; # 1 day, 86400 seconds verbose=1 debug() { [ $verbose -eq 1 ] && echo $* } lock_acquire() { debug "Acquiring lock ..." # # if lockfile is too old, remove it # if [ -f $LOCK_FILE ]; then tdiff=`perl -e '@a=stat("'$LOCK_FILE'");print time()-$a[9]'` if [ $tdiff -gt $too_old ]; then debug "Lock file ($LOCK_FILE) is older than 1 day, remove it" rm -f $LOCK_FILE fi fi spin=5 timeout=30 howlong=0 while : do if [ ! -f $LOCK_FILE ]; then touch $LOCK_FILE LOCK_STATUS=0 break fi sleep $spin (( howlong = howlong + spin)) if [ $howlong -gt $timeout ]; then LOCK_STATUS=1 break fi debug "Waited ${howlong}s for lockfile ($LOCK_FILE) to be released" done if [ $LOCK_STATUS -eq 1 ]; then debug "ERROR. Unable to acquire lock. Exit." exit 1 fi debug "OK. Lock ($LOCK_FILE) acquired." return $LOCK_STATUS } lock_release() { if [ $LOCK_STATUS -eq 0 ]; then debug "Releasing lock ($LOCK_FILE)" rm -f $LOCK_FILE > /dev/null 2>&1 fi } lock_acquire # ----- main program ------ debug "Do something" sleep 30
Try to run this script in a few terminals to have a feel yourself.
Labels: shell script
0 Comments:
Post a Comment
<< Home