Matt Damon
Matt Damon

Reputation: 333

Creating lock files shell

I'm currently creating a lock folder which is created when my script runs, I also move files into sub folders here for processing. When the script ends a TRAP is called which removes the lock folder and contents, all of which is working fine. We had an issue the other day when someone pulled the power from one of the servers so my TRAP was never called so when re-booted the lock folder was still there which meant my scripts couldn't re-start until they were manually removed. What's the best way of checking if the script is already running ? I currently have this approach using process id's:

if ! mkdir $LOCK_DIR 2>/dev/null; then  # Try to create the lock dir. This should pass successfully first run.
    # If the lock dir exists
    pid=$(cat $LOCK_DIR/pid.txt)
    if [[ $(ps -ef | awk '{print $2}' | grep $pid | grep -v grep | wc -l) == 1 ]]; then 
        echo "Script is already running" 
        exit 1
    else
        echo "It looks like the previous script was killed. Restarting process." 
        # Do some cleanup here before removing dir and re-starting process. 

    fi
fi

# Create a file in the lock dir containing the pid. Echo the current process id into the file. 
touch $LOCK_DIR/pid.txt
echo $$ > $LOCK_DIR/pid.txt

# Rest of script below

Upvotes: 1

Views: 2567

Answers (2)

meuh
meuh

Reputation: 12255

Many systems nowadays use tmpfs for directories like /tmp. These directories will therefore always be cleared after a reboot.

If using your pid file, note you can easily see the command running under that pid in /proc/$pid/cmdline and /proc/$pid/exe.

Upvotes: 0

Andrew Porter
Andrew Porter

Reputation: 156

Checking /proc/ and cmdline is a good call - especially as at the moment you are simply checking that there isn't a process with the process id and not if the process is actually your script.

You could still do this with your ps command - which would offer some form of platform agnosticism.

COMMAND=$(ps -o comm= -p $pid)
if [[ $COMMAND == my_process ]]
then
    .....

Note the command line arguments to ps limit it to command only with no header.

Upvotes: 1

Related Questions