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.
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
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
pidof -x not work for me.
> 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
Thank Jay for the script. works like a charm!