39

Regarding that thread: bash flock: exit if can't acquire lock

I'll appreciate if someone can explain to me what does the '200' stand for.

I've read about flock and it seems that 200 if to specify a File Descriptor, but what is so good about this number?

Community
  • 1
  • 1
Subway
  • 5,286
  • 11
  • 48
  • 59

1 Answers1

62

Theres nothing special about the number 200. It just happens to be the example used in the man page of the flock command; and it happens to be a large number, so it's unlikely to conflict with the the file descriptor of any other file you open during your script.

In your comment, you ask about:

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

The parentheses () create a subshell; a new process, separate from the parent process. The 200>/tmp/blah.lockfile causes that process to open up /tmp/blah.lockfile for writing, on file descriptor 200. The commands inside the parentheses are executed within that shell.

flock -e 200 obtains an exclusive lock on the file pointed to by file descriptor 200. An exclusive lock means that anyone else who tries to obtain a lock on that file, either exclusive or shared, will block (wait) until this lock has been relinquished, or fail if they hit a timeout or asked not to block. So during the remainder of the body of the subshell (the echo and sleep commands), the lock will be held by that subshell, and no one else can obtain that lock. Once the subshell finishes, the file will be closed and lock relinquished.

Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • Thanks. I'm new to bash scripting, could you please explain to me the rest of the code: `( flock -e 200 echo "In critical section" sleep 5 ) 200>/tmp/blah.lockfile echo "After critical section"` – Subway Nov 25 '12 at 14:34
  • Thanks! There is one thing I don't understand, though. Why is the subshell necessary for? Why not just take the lock before executing the code and let it go after the code execution has finished ? – Subway Nov 25 '12 at 16:11
  • 7
    @Rapher It's not technically necessary; you could take the lock before executing the code, and release it after. However, it makes it convenient to manage the lock; you are guaranteed that the lock will be dropped when the subshell exits, so you can't forget to drop the lock (or fail to drop it for some other reason), and it's easy to see the range for which the lock applies by just matching parentheses. – Brian Campbell Nov 25 '12 at 16:29
  • 1
    Thanks for the answer. Anyway, is there an easy way to make sure there's no conflict? "Unlikely" may not always be enough. – didi_X8 Sep 29 '14 at 19:22
  • 1
    @didi_X8 Use a real programming language and not Bash. Bash is for quick and dirty scripts; if you want guarantees about behavior, it's best not to use a language that has so many weird and surprising behaviors (like executing the content of environment variables). That said, in Bash you don't open new file descriptors unless you explicitly do a redirection using that file descriptor; `exec 3>/some/file`, or a subshell with a similar numbered redirect. So you can just keep track of the numbers manually, keeping in mind that 0, 1 and 2 are stdin, stdout, and stderr. – Brian Campbell Sep 29 '14 at 22:33
  • Great answer. Thanks! I was also wondering about these exact same issues. (the parentheses and the 200). – so.very.tired Jul 08 '16 at 14:37
  • 4
    so if you are using this technique in multiple scripts, you use different numbers? or different lock file names? – Kalpesh Soni Jun 13 '17 at 18:05
  • It seems that if I run two instances of the same script with this code in parallel that one of them never obtains the lock and just sits there. Any thoughts? – Sander Verhagen Oct 07 '18 at 20:28
  • @SanderVerhagen Usually that's what you try to achieve with a lock - not being able to run more than one instance of the same thing at the same time. – bryn Mar 01 '19 at 15:03
  • Obviously (?!) what I meant was: never obtains the lock _after other process(es) have gone away_. But I moved on to a different solution, thank you. – Sander Verhagen Mar 01 '19 at 19:41
  • What happens if you use the same number for two different files? `200>/tmp/${client_one}.lockfile` and `200>/tmp/${client_two}.lockfile` Will they conflict? the idea is that we call the same bash script, once per client. – Frank Forte Jun 01 '23 at 19:16