HOW TO USE A LOCKFILE FROM A SHELL SCRIPT DAEMON June 6, 2007 Copyright (c)2007 Hiro Sugawara Distributed under terms of GPL 2.0 Every once in a while, I create local daemon programs to do a variety of jobs in Bash script. In order to prevent more than one instance (process) of the same daemon from running, it is necessary to implement a locking mechanism. Traditionally, lock files have been used for this purpose for their simplicity and portability (among different version of *nix). The algorithm of use of a lock file is described in the following pseudo code. lockfile="/var/run/mylock.pid" while fd=creat lockfile READONLY fails do pid=read lockfile if process pid exits then log "Another instance of this daemon is running" exit FAIL fi delete lockfile done write mypid to fd close fd The key is that "creat" fails if there's already a lockfile since it's read-only or otherwise it would create a new lockfile _atomically_ without a race. Unfortunately, there are (at least) two problems with this algorithm for implementing in a Bash script: 1) If the start-up script spawns the daemon process as a background process within the same script, which I very often do, the daemon process cannot directly tell its own process ID because the "$$" variable represents the parent (i.e. start-up) process rather than the daemon. For example, the following script code may show a different process ID from your expectation. start() { echo $$ # Not the child's but parent's } case $1 in start) start & # Start background daemon using a local function ;; ... 2) A daemon process usually runs as root, and a create/write-open attempt on a read-only file never fails by definition. Here are my solutions to the above issues. 1) Process ID The daemon process's current process ID can be obtained as its child process's parent process ID. So, the following will set 'pid' the current shell script's process ID no matter how the current shell script process was started. pid=`sh -c 'echo $PPID'` 2) Read-only protection Running the lock file handling as a non-root user makes a create/ write-open attempt on a read-only file fail. So. let's use the "daemon" user for this. piddir=/var/run/mypiddir pidfile=$piddir/mylock.pid mkdir -p $piddir chown daemon $piddir pid=`sh -c 'echo $PPID'` while ! sudo -u daemon sh -c "umask 333; echo $pid > $pidfile" 2> /dev/null do hispid=`cat $pidfile` if echo "$hispid" | grep -qE '^[[:digit:]]+$' && kill -s 0 "$hispid" 2> /dev/null then echo "Another instance (process) of $myname already running" >&2 exit 1 fi rm $pidfile sleep 2 done The "mypiddir" directory is used so that the daemon user can create a new file there. -eof-