I want to make a sh script that will only run at most once at any point.
Say, if I exec the script then I go to exec the script again, how do I make it so that if the first exec of the script is still working the second one will fail with an error. I.e. I need to check if the script is running elsewhere before doing anything. How would I go about doing this??
The script I have runs a long running process (i.e. runs forever). I wanted to use something like cron to call the script every 15mins so in case the process fails, it will be restarted by the next cron run script.
Write the process id into a file and then when a new instance starts, check the file to see if the old instance is still running.
You want a pid file, maybe something like this:
From example in flock(1) man page. Very practical for using in shell scripts.
I think you need to use lockfile command. See using lockfiles in shell scripts (BASH) or http://www.davidpashley.com/articles/writing-robust-shell-scripts.html.
The second article uses "hand-made lock file" and shows how to catch script termination & releasing the lock; although using
lockfile -l <timeout seconds>
will probably be a good enough alternative for most cases.Example of usage without timeout:
Will ensure that any second script started during this one will wait indefinitely for the file to be removed before proceeding.
If we know that the script should not run more than X seconds, and the
script.lock
is still there, that probably means previous instance of the script was killed before it removedscript.lock
. In that case we can telllockfile
to force re-create the lock after a timeout (X = 10 below):Since
lockfile
can create multiple lock files, there is a parameter to guide it how long it should wait before retrying to acquire the next file it needs (-<sleep before retry, seconds>
and-r <number of retries>
). There is also a parameter-s <suspend seconds>
for wait time when the lock has been removed by force (which kind of complements the timeout used to wait before force-breaking the lock).I just wrote a tool that does this: https://github.com/ORESoftware/quicklock
writing a good one takes about 15 loc, so not something you want to include in every shell script.
basically works like this:
the above calls this bash function:
when the script exits, it automatically releases the lock using trap
to manually release the lock at will, use
ql_release_lock
:You can use the
run-one
package, which providesrun-one
,run-this-one
andkeep-one-running
.The package: https://launchpad.net/ubuntu/+source/run-one
The blog introducing it: http://blog.dustinkirkland.com/2011/02/introducing-run-one-and-run-this-one.html