This example was contributed by Charles Duffy. It has been separated from the parent page because the code has several issues that make it dubious.
Are we sure this code's correct? There seems to be a discrepancy between the names LOCK_DEFAULT_NAME and DEFAULT_NAME; and it checks for processes in what looks to be a race condition; and it uses the Linux-specific /proc file system and the GNU-specific egrep -o to do so.... I don't trust it. It looks overly complex and fragile. And quite non-portable. -- GreyCat
LOCK_DEFAULT_NAME=$0 LOCK_HOSTNAME="$(hostname -f)" ## function to take the lock if free; will fail otherwise function grab-lock { local PROGRAMNAME="${1:-$DEFAULT_NAME}" local PID=${2:-$$} ( umask 000; mkdir -p "/tmp/${PROGRAMNAME}-lock" mkdir "/tmp/${PROGRAMNAME}-lock/held" || return 1 mkdir "/tmp/${PROGRAMNAME}-lock/held/${LOCK_HOSTNAME}--pid-${PID}" && return 0 || return 1 ) 2>/dev/null return $? } ## function to nicely let go of the lock function release-lock { local PROGRAMNAME="${1:-$DEFAULT_NAME}" local PID=${2:-$$} ( rmdir "/tmp/${PROGRAMNAME}-lock/held/${LOCK_HOSTNAME}--pid-${PID}" || true rmdir "/tmp/${PROGRAMNAME}-lock/held" && return 0 || return 1 ) 2>/dev/null return $? } ## function to force anyone else off of the lock function break-lock { local PROGRAMNAME="${1:-$DEFAULT_NAME}" ( [ -d "/tmp/${PROGRAMNAME}-lock/held" ] || return 0 for DIR in "/tmp/${PROGRAMNAME}-lock/held/${LOCK_HOSTNAME}--pid-"* ; do OTHERPID="$(echo $DIR | egrep -o '[0-9]+$')" [ -d /proc/${OTHERPID} ] || rmdir $DIR done rmdir /tmp/${PROGRAMNAME}-lock/held && return 0 || return 1 ) 2>/dev/null return $? } ## function to take the lock nicely, freeing it first if needed function get-lock { break-lock "$@" && grab-lock "$@" }