Monday, 1 February 2016

Using flock in bash without invoking a subshell

flock -c can call external commands but not bash functions. Consequently users mess about with file descriptors, and often making a mess of it.

Inspired by Ivan's post http://blog.famzah.net/2013/07/31/using-flock-in-bash-without-invoking-a-subshell I've written a flock wrapper for bash, that uses flock underneath but allows flock -c to work for bash functions.

It can be called just like the regular flock command, with the benefit that the -c invocation is supported for bash functions; so you can use it like this:

flock -o /tmp/process my_thing "$@"

and I strongly recommend the -o option so that the file descriptor used for the lock is not passed to any sub-processes, which could be problematic if long live sub-processes (e.g. re-spawned daemons) keep it open.

It will pass through and invoke the regular flock if the command isn't a bash function, or if you aren't trying to execute a function.

Sadly, it doesn't recognize bash built-in's.

But the good news is, you can use flock -o ...file... on a shell function inside your shell script without having to worry about file descriptors.

# Helper function (in order to preserve $@ in the caller)
# If this isn't used to call a shell function then return 0
# otherwise return $? as the argumment number which represents
# the command/function to be called
_is_standard_flock() {
  local args=$#
  # find the first argument that doesn't begin with a -
  while test $# != 0
  do case "$1" in
     -*) shift ; continue ;;
     *) break ;;
     esac
  done

  # if it is numeric and there are not additional arguments 
  test $# = 1 -a -n "$1" -a -z "${1//[0-9]}" && return 0
  shift
  # (skipping -c if present)
  # or the following argument is also not a shell function then use the original flock
  if test "$1" = "-c"
  then declare -F "$2" >/dev/null || return 0
  else declare -F "$1" >/dev/null || return 0
  fi

  # we can't have shifted many args if this is a legitimate use of flock
  # so we will be in range of the exit code
  return $(( args - $# + 1))
}

# Help function to determine if -o or --close was given in the flock arguments
_wants_close() {
  test "${*/#--close/}" != "$*" && return # will also match bogus arguments like --closed
  # remove any -- options
  set -- "${@/#--*/}"
  # look for options with o
  test "${*/#-*o/}" != "$*" && return
  return 1
}

flock() {
  if _is_standard_flock "$@"
  then : # do outside the if-clause so bash can optimise exec where possible
  else # save the exit code (offset) as $1
       set -- $? "$@"
       # ${!$1} is the lock file 
       # ${@:$(($1 + 1))} might be -c
       test "${@:$(($1 + 1)):1}" = "-c" && set -- "${@:1:$1}" "${@:$(($1 + 2))}"
       if _wants_close "${*:2:$(( $1 - 1))}"
       then { set -- "$1" "$_" "${@:2}" ; command flock "${@:3:$(( $1 - 2))}" $2 && eval '"${@:$(( $1 + 2))}"' "$2>&-" ; set -- $? $2 ; command flock -u $2 ; return $1 ; } {_}<"${!1}"
       else { set -- "$1" "$_" "${@:2}" ; command flock "${@:3:$(( $1 - 2))}" $2 &&       "${@:$(( $1 + 2))}"          ; set -- $? $2 ; command flock -u $2 ; return $1 ; } {_}<"${!1}"
       fi
  fi
  command flock "$@"
}

x

9 comments:

  1. A 2-hour journey is going to fascinate you with both the sides of Dubai. Either you in favor of getting enchanted by the historical aspects of Dubai or you want to get amused by sky-high buildings of advanced city; one of the Best Dhow Cruise Dubai will take you either to the Creek or Marina as per your demand https://dhowcruisedubai.net/.

    ReplyDelete
  2. Latest Gogoanime HD SUb Eng Videos Online, Watch gogoanime online in high quality ,Free download gogo anime, Gogoanime videos English SUB HQ,

    ReplyDelete

  3. In each dialogue box, the movies chronologically segregated in descending order. This site is very organized
    and very possible. The film can be searched alphabetically. From 0-9 and the alphabets individually can be searched.
    Hollywood, Bollywood, Malayalam, Tamil and Telugu movies. Once you open the website, you will be able to see a range of
    options.123Movies, GoMovies, GoStream, MeMovies or 123movieshub,movierulz,hindi movies,Bollywood | Hollywood | Songs | Punjabi
    | Hindi Dubbed | Songs | Hindi Webseries Season | Netfilix | ULLU App

    In a separate dialogue box, we can search by the plethora of the genres provided to us. Action, animation, adventure, biography,
    comedy, crime, documentary, drama, family, fantasy, film-noir, game show, history, horror, music, musical, mystery, news, reality
    show, romance, sci-fi, sports, talk- show, thriller, war and western and various genres can be found here.

    ReplyDelete
  4. Thankyou for your kind information. visit our website and download fastunlocker frp bypass apk

    ReplyDelete
  5. i love reading your blog posts. thankyou. visit this link and get remote codes. click here https://myuniversalremotecodes.com/comcast-xfinity-universal-remote-codes/

    ReplyDelete
  6. If you have more than a couple of best auger posthole digger to dig, don't stop at a shovel and a clamshell digger. You'll treasure two more tools just as much. Pick up a tile spade. The long, narrow blade will get you places no other shovel can.

    ReplyDelete
  7. can you weld brass to steel? Due to the extremely different welding points, you cannot weld Brass and steel together as it becomes considerably tricky. You can, however, use the brazing technique to join the two materials together.

    ReplyDelete
  8. A best swiss army knife having a non-locking blade with a blade-length less than 3 inches is usually legally allowed to be carried in the pocket in almost all countries. Such Swiss Army Knives are considered as pocket knives and are viewed as tools rather than weapons.

    ReplyDelete
  9. Professional custom and luxury home renovation and improvement services in Toronto and Richmond Hill at affordable cost. Service BLOG

    ReplyDelete