3

Am new to shell scripting, and it makes me wonder why the following snippet does not work in zsh but does in bash? Is there a zsh equivalent of the same snippet? I get error parse error near `200'

( 
  flock -e 200
  echo "In critical section"
  sleep 5 
) 200>/tmp/blah.lockfile 
echo "After critical section"

The above snippet of code is from src: https://stackoverflow.com/a/13551882/15087532

11
  • 1
    Please see this unix.stackexchange.com/a/475427/487543
    – Alex
    Sep 9 at 19:54
  • 1
    @schily I would prefer not to hardcode a number, online forums seem to suggest that the number 200 was chosen in example as its unlikely a script would have opened as many files. Is there a automatic way of getting a file descriptor?
    – reportaman
    Sep 9 at 21:53
  • 2
  • 3
    You can only rely on file descriptor numbers below 10 to be available in a portable script. Also zsh has a built-in flock in its zsystem module that would be better to use in zsh scripts.
    – Kusalananda
    Sep 10 at 5:40
  • 1
    Even in bash or yash (the two Bourne-like shells I know that allow using fds above 9 explicitly), doing it is dangerous as if you happen to use a fd that the shell uses internally that will fail (with an error in yash, silently in bash). yash does extent the range of fds you can safely you to 0-99 though. Sep 10 at 5:57
3

Don’t hardcode the fd. Let the shell acquire it for you:

(
  unset fd
  exec {fd}> /tmp/blah.lockfile
  flock -e $fd
  echo "In critical section"
  sleep 5 
)
echo "After critical section"

PS: This works in Bash, too.

4
  • FYI, that feature was implemented in zsh, ksh93 and bash at the same time following discussion between maintainers of all three shells. IIRC, proposal was by Oliver Kiddle, one of zsh maintainers. Sep 10 at 11:21
  • In other words, this is a method that you definitely should not use if you like to create portable scripts that work with POSIX shells.
    – schily
    Sep 10 at 11:25
  • 1
    @schily, given how the Q asked for a solution that works in zsh, while presenting one that works in Bash (only), that's hardly a fault in this answer. Also, I don't see your answer with a POSIX-compatible solution either.
    – ilkkachu
    Sep 10 at 12:35
  • In one of the linked questions, there's was a version of this with ( flock -e $fd; ... ) {fd}>/some/lockfile, but for some reason zsh doesn't seem to parse that, even though it supports {var}>whatever on a simple command (or with exec, as here)
    – ilkkachu
    Sep 10 at 13:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.