2

After looking into flock I'm a bit confused. Basically there are two forms:

flock [options] <file|directory> <command> [command args]
flock [options] <file descriptor number>

Now if I want to use the second form I need to use exec 200<> file. Then I lock the file with flock 200.

Now I prevented my script from mutilating file because it needs to acquire the lock before doing so. Still why did I have to create the descriptor first? I can operate on file perfectly fine without using that descriptor.

So why am I forced to create a descriptor?

mjb4
  • 989
  • 1
  • 9
  • 14
  • You need to create a descriptor because you are using a command that expects a file descriptor. If you don't want to create a descriptor, use the first form. – chepner Mar 18 '14 at 17:31
  • @chepner yeah obviously put the first form takes the command directly I use the file a lot with a lot of commands in between acquiring the lock and freeing it again. So I can't use the first one – mjb4 Mar 18 '14 at 17:35
  • ah and I do not want to open a subshell – mjb4 Mar 18 '14 at 17:35
  • @mjb4, one of the key things to understand about `flock` is that you don't need to call `flock -u` to release a lock -- it's release as soon as the file descriptor it's attached to is closed. Thus, if you didn't hold the descriptor open, you'd have no way to make your lock last across multiple commands. – Charles Duffy Mar 18 '14 at 18:51

2 Answers2

4

One of the primary advantages of using flock() -- or the fcntl(LOCK_EX) mechanism it's closely related to -- over more traditional locking mechanisms is that there's no need to perform cleanup on reboot or other unclean shutdown scenarios.

This is possible because the lock is attached via a file descriptor; when that file descriptor is closed -- whether by a graceful shutdown, a SIGKILL or a power loss -- the lock is no longer held.

When you use the underlying flock() syscall -- which the flock command-line tool invokes -- that lock lasts as long as your file descriptor does. Consequently, if you want a single lock on a file to be open for the duration of multiple commands, you need a descriptor to be held through that time period.

If flock didn't have this design requirement, it would have no way of automatically closing and cleaning up locks whenever the processes associated with them exit. This would make flock far less useful.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • ok thx, thats quite an interessting reason and indeed usefull! So what you also indicate is that even thought I use that descriptor just as mutex (which is pretty implicit) I should keep on doing so and don't care that I opened that descriptor. – mjb4 Mar 18 '14 at 19:42
  • A forgot to put it in terms of a question! Is there a more explicit way on achiving this file lock, or is this the 'default' way on achiving a lock? – mjb4 Mar 18 '14 at 19:53
  • @mjb4 I'm sorry -- I don't quite understand what you mean by the question. More explicit than what? ("on achiving"?) – Charles Duffy Mar 18 '14 at 19:54
  • hmm, maybe it's just my feeling. But opening a filedescriptor and then not using it but altering the file without using that descriptor seems very implicit for me. As a descriptor is not supposed to be a mutex! – mjb4 Mar 18 '14 at 19:57
  • ...anyhow, don't think of the descriptor as the mutex itself, but as the *handle* on the mutex. – Charles Duffy Mar 18 '14 at 20:06
  • hmm the syntax is quite nice but won't work in my case. If the descriptor is the handle on the mutex, that does not mean that the file itself is the mutex or? – mjb4 Mar 18 '14 at 20:21
  • @mjb4, The lock is on the file (or, rather, the inode) itself, and yes, anyone else trying to get a conflicting lock on that same file will block. Wouldn't be much good otherwise. – Charles Duffy Mar 18 '14 at 21:36
2

The flock(2) system call -- and therefore the flock command -- can only lock open files while they're open. Once the file handle is closed, the lock is released.

Since all open file handles are closed when the command exit, there's no way to run flock filename to lock a file.

The file either has to be opened in advanced so that it's not closed when flock exits, or it can be opened by flock and operated on by a command that flock invokes, until the command and flock exits, releasing the lock.

that other guy
  • 116,971
  • 11
  • 170
  • 194
  • 1
    I wouldn't quite say "no way". See the `getLock` function given in http://stackoverflow.com/questions/24388009/linux-flock-how-to-just-lock-a-file/24389468#24389468. Of course, that's just sugar around handling FDs, but it's sugar that might be helpful to people looking at this question. :) – Charles Duffy Sep 15 '15 at 22:24