Skip to content

Instantly share code, notes, and snippets.

@rafdouglas
Last active June 19, 2017 14:49
Show Gist options
  • Save rafdouglas/45c56cffb0e1110a62093ed3e7eb4b6e to your computer and use it in GitHub Desktop.
Save rafdouglas/45c56cffb0e1110a62093ed3e7eb4b6e to your computer and use it in GitHub Desktop.
automagic pid lock manager for bash script
#!/bin/bash
#
# Latest version at:
#
# https://gist.github.com/rafdouglas/45c56cffb0e1110a62093ed3e7eb4b6e
#
# will automatically take care of:
# - if not present, create a pidlock dir with the name of the caller script/shell
# - if present, honour it by warning and exiting
# - delete the pidlock dir when exiting, even by ctrl-c or kill (not kill -9)
#
# use of lock directories instead of files is superior because the process is atomic
# http://mywiki.wooledge.org/BashFAQ/045
#
# [--- QUOTE ---]
# Note that we cannot use mkdir -p to automatically create missing path components:
# mkdir -p does not return an error if the directory exists already,
# but that's the feature we rely upon to ensure mutual exclusion.
# [--- UNQUOTE ---]
#
# @RafDouglas 170619
#
# HOW TO USE
#
# use this simply by sourcing it in your original script:
# . ~/your_directory/lock_manager.sh
# Make sure that pid_dir is:
# - writable and
# - volatile,
# so you don't leave stale pidlock dirs across reboots.
# A (possibly smarter) alternative would be to use flock
pid_dir='/var/run/'
caller_name=$(basename $0)
caller_pid=$$
dying_sub() {
echo "$caller_name"' ('"$caller_pid"') exiting. removing pidlock.'
rm -fr -- "$mypiddir"
}
mypiddir="$pid_dir""$caller_name"'.pid'
if ! mkdir "$mypiddir" 2>/dev/null; then
# Let_s check if we can read the pid of ght locking process.
if [ -e "$mypiddir"'/pid' ]; then
locking_pid=$(cat "$mypiddir"'/pid')
echo 'Myscript is already running locked by PID '"$locking_pid" >&2
else
echo 'Myscript is already running. Or cannot create '"$mypiddir" >&2
fi
exit 0
fi
# Make sure pidlock dir is removed on program exit.
trap dying_sub EXIT
#SIGKILL is of course not usable
# Create a file with current PID to indicate that process is running.
echo $$ > "$mypiddir"'/pid'
write_error=$?
if [ "$write_error" -gt 0 ]; then
echo 'ERROR: not able to write to: '"$mypiddir"'/pid . Exiting.'
exit 2
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment