Home > Uncategorized > One instance at a time with PID file in Bash

One instance at a time with PID file in Bash

Often times, I only want a script to run one instance at a time. For example, if the the script is copying files, or rsync’ing between systems, it can be disastrous to have two instances running concurrently, and this situation is definitely possible if you run the script from cron.

I figured out a simple way to make sure only one instance runs at a time, and it has the added benefit that if the script dies midway through, another instance will start – a drawback of just using lock files without a pid.

Without further ado, here’s my script:

#!/bin/bash
pidfile=/var/run/sync.pid
if [ -e $pidfile ]; then
pid=`cat $pidfile`
if kill -0 &>1 > /dev/null $pid; then
echo "Already running"
exit 1
else
rm $pidfile
fi
fi
echo $$ > $pidfile
 
#do your thing here
 
rm $pidfile

CC BY-SA 4.0 One instance at a time with PID file in Bash by Craig Andrews is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Categories: Uncategorized Tags:
  1. February 16th, 2009 at 18:56 | #1
    Related and probably interesting to you: over at the sysadvent log there’s an article on best lockfile practices.
  2. Gerard Seibert
    November 30th, 2009 at 07:18 | #2
    I modified your script slightly. It works on Bash and does not create a ‘1’ file. Using the ‘f’ flag with ‘rm’ also prevents useless error messages.

    PID_FILE=”/var/run/my_prog.pid”

    ## Check to see if the program is running
    if [[ -e ${PID_FILE} ]]; then
    ## Capture the ‘pid’ number in ‘pid’ variable
    pid=$( ${PID_FILE}

    do something

    ## Remove the pid file if it exists
    if [[ -e ${PID_FILE} ]]; then
    rm -f ${PID_FILE}
    fi

  3. Jonathan
    August 27th, 2010 at 22:06 | #3
    Hi,

    Your syntax is a bit wrong, when I ran the command the output of kill got redirected to the file 1.

    Here is the syntax that worked for me:

    if kill -0 $pid > /dev/null 2>&1; then
    echo “Already running”
    exit 1
    else
    rm $pidfile
    fi
    fi
    echo $$ > $pidfile

  4. Sharad Agarwal
    September 11th, 2010 at 12:31 | #4
    Maybe we can try to modify your run_one_instance.sh script a bit to make it so that the can be any other script?

    No copy/paste that way, and makes it more interesting 🙂

  5. Craig
    May 11th, 2011 at 10:09 | #5
    You should also check if they process_id that is running is actually the same script. The system could release the script and then re-issue that process_id to another program.
  6. February 10th, 2014 at 14:47 | #6
    The main problem with this approach is not how it determines if the process is already running, but rather that two calls to *this* script simultaneously could prevent a false-positive, defeating the purpose entirely.

    Better off to go for a locking approach IMO.

    http://stackoverflow.com/questions/1715137/the-best-way-to-ensure-only-1-copy-of-bash-script-is-running

  1. October 7th, 2015 at 02:47 | #1