I’ve added the “force” options, as I needed it for the project I’m working on.
#!/bin/bash usage() { echo "usage: setlock [ -fFnN ] [ -xX ] [ -v ] [ -V ] file program [ arg ... ]" echo " Options" echo " -f: No delay. If fn is locked by another process, try to force ownership by trying to kill the process that has the lock." echo " -F: No delay. If fn is locked by another process, bruteforce ownership by killing the process that has the lock (-9)." echo " -n: No delay. If fn is locked by another process, setlock gives up." echo " -N: (Default.) Delay. If fn is locked by another process, setlock waits until it can obtain a new lock." echo " -x: If fn cannot be created or locked, setlock exits zero." echo " -X: (Default.) If fn cannot be created or locked, setlock prints an error message and exits nonzero." echo " -v: Verbose messaging" echo " -V: Show the version" exit 1 } version() { echo "Version 0.1" usage } verbose() { if [ "$VERBOSE" = "y" ] ; then echo "$1" fi } cleanup() { if [ "$SETLOCK" = "y" ] ; then killlock clear_lock fi } trap "cleanup" set_lock() { verbose "set lock" echo $$ >> $LOCK SETLOCK=y } clear_lock() { verbose "Clear lock" rm $LOCK >/dev/null 2>&1 } killlock() { pids=`cat $LOCK 2>/dev/null` for pid in $pids do verbose "Kill $1 on process $pid" kill $1 $pid >/dev/null 2>&1 done } run_command() { set_lock verbose "Running command" eval bash -c "$CMD" RET=$? verbose "Command done - exit value = $RET" clear_lock RET=$? exit $RET } no_wait() { verbose "No waiting" exit $EXITCODE } wait_nice() { verbose "Waiting nice" while [ -f "$LOCK" ] ; do sleep 1 done run_command } force_kill() { killlock run_command } force_brute() { killlock -9 run_command } FORCE=n DELAY=y EXITCODE=1 VERBOSE=n OPTS=0 while getopts "f F n N x X v V" o ; do case $o in f) FORCE=y DELAY=n;; F) FORCE=b DELAY=n;; n) DELAY=n;; N) DELAY=y;; x) EXITCODE=0;; X) EXITCODE=1;; v) VERBOSE=y;; V) version;; esac let OPTS=$OPTS+1 done if [ $# -lt 2 ] ; then verbose "Not enough parameters given" usage fi APTS=0 while [ $APTS -lt $OPTS ] ; do shift let APTS=$APTS+1 done LOCK=$1 shift CMD=$* if [ -z "$LOCK" ] ; then verbose "No lockfile given" usage fi if [ -z "$CMD" ] ; then verbose "No command given" usage fi if [ -f "$LOCK" ] ; then if [ "$DELAY" = "y" ] ; then wait_nice else case "$FORCE" in "n") no_wait;; "y") force_kill;; "b") force_brute;; *) exit 99;; esac fi else run_command fi
Feel free to use it, yet I’m publishing it here under the GPL license