Stop Shell Script Overlaps: How to Prevent Multiple Instances from Running Simultaneously

Stop Shell Script Overlaps: How to Prevent Multiple Instances from Running Simultaneously

It often happens that a script is set up in a crontab to run regularly, but the script does not finish running in time for the crontab to run it again. This can cause errors in the script or even overload the system.

The solution

To solve this, I have written the following code to prevent the same script from running multiple times at the same time.

lockfile="/tmp/$(basename "$0").lock"
[ -f "$lockfile" ] && ps -p $(cat $lockfile) > /dev/null && echo "$(basename "$0") is still running." && exit || echo $$ > $lockfile

This code first defines a .lock file to store the PID of the currently running shell script. If this PID exists in the system (i.e. the script is running), then we print a text and exit. If it is not running or the file does not exist, we store the PID in this file. The code always tells you which script it is.

Use this in multiple scripts

If you want to use it in multiple scripts, it's a good idea to put it in a central file and then refer to it as a function, like this:

# Prevent the same script from running multiple times at the same time
PreventMulipleRun() {
        lockfile="/tmp/$(basename "$0").lock"
        [ -f "$lockfile" ] && ps -p $(cat $lockfile) > /dev/null && echo "$(basename "$0") is still running." && exit || echo $$ > $lockfile
}

In this case, don't forget to call the external file in all your scripts:

. /path/to/central.file

Debug mode

It might also be a useful idea to enable debug mode in case the previously started script didn't run and you want to know why

# Prevent the same script from running multiple times at the same time
PreventMulipleRun() {
        lockfile="/tmp/$(basename "$0").lock"
        if [ -f "$lockfile" ]; then
                CURRPID="$(cat $lockfile)"
                if ps -p $CURRPID > /dev/null; then
                        printf "$(basename "$0") is still running.\n\nDebug:\n$(pstree -pal $CURRPID)"
                        exit
                else
                        echo $$ > $lockfile
                fi
        fi
}

 

That's all.

If you have any questions, feel free to ask in the comment section!

If you found this article useful and would like to show your appreciation, please consider making a small donation via PayPal. Your support will allow me to continue creating valuable content and make my blog even better. Thank you for your contribution!

Comments