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.

5 Comments

  1. > 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