Bash: How to check if your script is already running

Sometimes, you don’t want a script to run when it is already running. Maybe it is scheduled as a cronjob but the previous run of that cronjob hasn’t finished yet.
I usually do some “pre-flight checks” in almost every script I write. And most times, this is one of them.

Here’s how:

#!/bin/bash
 
# check if we are the only local instance
if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then
	echo "This script is already running with PID `pidof -x $(basename $0) -o %PPID`"
	exit
fi
 
# start your script here

It’s that easy. It can even be made a one-liner:

if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then exit; fi

pidof (program name here) returns the process ID(s) of every running instance of the specified program. The -x switch tells pidof to include scripts, these are usually excluded. $(basename $0) is being replaced by the name of your script when you execute it, and the -o switch omits a given PID or, in this case, the PID of this very script, that’s what the special %PPID parameter is for. So when this script is run and the check fires, it won’t count itself.

One more thing: You must call your scripts directly, like ./something.sh, or like this sh -c something.sh (thanks Mike), for this to work.

7 Comments

  1. yuck, great idea but to change the way a script is called to get the code to work bothers me. I would do this instead:

    # check if we are the only local instance
    cnt=$(ps -ef | grep $(basename $0) | grep -v “grep” | head -1 |wc -l)
    if [ $cnt -gt 0 ]; then
    echo “Script ( $(basename $0) ) is already running, quitting ..”
    exit
    fi

    1. check if we are the only local instance
      if [ $(ps -ef | grep $(basename $0) | wc -l) -gt 3 ] ; then
      echo “Script ( $(basename $0) ) is already running, quitting ..”
      exit
      fi

  2. > You must call your scripts directly, like ./something.sh, NOT like sh something.sh, otherwise this trick will not work.
    > This means your script needs to have the executable flag set (chmod +x it).

    Running the script with sh -c, like sh -c ./something.sh also works fine. Important as cron tasks are run with /bin/sh -c /path/to/something.sh

Leave a Reply

Your email address will not be published. Required fields are marked *