Protecting a bash script against concurrent execution.
This is very simple and easy in bash and probably fine in sh (not tested). The lockfile is never deleted but that is not an issue.
exec 9>>mylockfile
if ! flock --exclusive --nonblock 9; then
echo "$(date -u +"%FT%T.%3NZ") $$: scriptname will wait for lock"
flock --exclusive 9
echo "$(date -u +"%FT%T.%3NZ") $$: scriptname finished waiting for lock"
fi
... this code is protected against concurrency ...
It's easy enough to adjust that to exit if the script is already running:
exec 9>>mylockfile
if ! flock --exclusive --nonblock 9; then
echo "scriptname already running, exiting"
exit 1
fi
... this code is protected against concurrency ...
The lock is automatically released once the file descriptor is closed (which is inherited by subshells or things you exec from the shellscript, so all that needs to close). Thus the rest of the script is protected against concurrent execution. There is no issues with power loss and the lockfile staying around either.
See also: https://gist.github.com/przemoc/571091