Improved code to make a Bash script quit if it detects multiple running instances of itself
I've been using the following code in my Bash scripts to check if another instance of the same script is already running and quit:
if [ "$(pgrep -x $(basename $0))" != "$$" ]; then
echo "Error: another instance of $(basename $0) is already running"
exit 1
fi
Realized today that it doesn't always work. For instance, let's say I have scripts named test, test.with.multiple.periods and test_with_underscores:
$ ps aux | sed -n '/test/p'
ak 1186 0.0 0.0 10648 1516 pts/4 S 19:43 0:00 /bin/bash ./test
ak 1192 0.0 0.0 10648 1520 pts/4 S 19:43 0:00 /bin/bash ./test.with.multiple.periods
ak 1196 0.0 0.0 10648 1524 pts/4 S 19:44 0:00 /bin/bash ./test_with_underscores
The pgrep syntax I'd been using will match the first one:
$ pgrep -lx test
1186 test
But return nothing for the other two:
$ pgrep -lx test.with.multiple.periods
$ pgrep -lx test_with_underscores
The -f option fixes that:
$ pgrep -lfx "/bin/bash ./test"
1186 /bin/bash ./test
$ pgrep -lfx "/bin/bash ./test.with.multiple.periods"
1192 /bin/bash ./test.with.multiple.periods
$ pgrep -lfx "/bin/bash ./test_with_underscores"
1196 /bin/bash ./test_with_underscores
With that in mind, the updated version of the code to quit if another instance of the same script is already running, that works with all three examples above, is:
if [ "$(pgrep -fx "/bin/bash $0")" != "$$" ]; then
echo "Error: another instance of $(basename $0) is already running"
exit 1
fi
UPDATE 2012-12-13
The above won't work correctly if your script accepts arguments, here's a version that should correctly match scripts launched both with or without arguments:
if [ -z "$@" ]; then
if [ "$(pgrep -fx "/bin/bash $0")" != "$$" ]; then
echo "ERROR: another instance of '$(basename $0)' is already running"
exit 1
fi
else
if [ "$(pgrep -fx "/bin/bash $0 $@")" != "$$" ]; then
echo "ERROR: another instance of '$(basename $0) $@' is already running"
exit 1
fi
fi
3 Comments
1. sundar replies at 31st October 2013, 7:19 pm :
Thanks a lot buddy. You made my life easy. I just made one change in my script: /bin/sh instead of /bin/bash after noticing it on ps -ef Keep up your good work.
2. wes replies at 9th June 2014, 3:52 pm :
Thanks this helped
3. Anthony replies at 30th December 2014, 2:01 am :
Thank you it helped me to write a script without any lock file.
Leave a comment