145

I'd like to determine what process has ownership of a lock-file. The lock-files are simply a file with a specific name that has been created.

So, how can I determine what process has a particular file open in Linux? Preferably a one-liner type or a particular Linux tool solution would be optimal.

Jens Erat
  • 18,485
  • 14
  • 68
  • 80
Danny
  • 1,654

5 Answers5

156

On most Linux systems lsof NAME does the job:

fin@r2d2:~$ lsof /home/fin
COMMAND   PID USER   FD   TYPE DEVICE SIZE    NODE NAME
bash    21310  fin  cwd    DIR    8,1 4096 5054467 /home/fin
lsof    21320  fin  cwd    DIR    8,1 4096 5054467 /home/fin
lsof    21321  fin  cwd    DIR    8,1 4096 5054467 /home/fin
fin@r2d2:~$
TTM
  • 239
fin
  • 1,916
72

You can also use fuser for this:

~> less .vimrc
# put in background
~> fuser .vimrc
.vimrc:              28135
~> ps 28135
  PID TTY      STAT   TIME COMMAND
28135 pts/36   T      0:00 less .vimrc
9

Having a file open is not a lock because, if each process has to check whether the file is open first and not proceed if it is or create/open it if it isn't, then two processes could quite well check simultaneously, both find that it isn't open, then both create or open it.

To use a file as a lock, the check-and-lock operation has to be a single uninterruptable operation. You can achieve this in a Unix filesystem by creating a file with read-only mode and removing it to unlock. If the file exists (and is read only) the file creation will fail, so you get check-and-lock in a single atomic operation.

If your locking process is a shell script that will be running as a daemon, you can get this effect by using umask, a per-process setting that sets the permissions that new files are created with:

oldumask=$(umask)
umask 222   # create files unwritable to owner too
if echo $$ > /var/lock/foo
then
    : locking succeeded
else
    : locking failed
fi
umask $oldumask
This also writes the owning process' PID into the file, which solves your other problem: cat /var/lock/foo
As regards the specific question "Which processes have this file open?", this can be useful when you want to unmount a filesystem but can't because some process has a file open in it. If you don't have those commands available, you can ask /proc as root:

ls -l /proc/*/cwd | grep '/var/lock/foo$'

or, as a mortal user:

ls -l /proc/*/cwd 2>/dev/null | grep '/var/lock/foo$'

martinwguy
  • 1,090
7

If you want to know which exact process's file descriptor links to your file without lsof or fuser — search thru /proc:

$ find /proc -regex '\/proc\/[0-9]+\/fd\/.*' -type l -lname "*$1*" -printf "%p -> %l\n" 2> /dev/null

Replace $1 with the open filename you are searching for. You can amend the -printf for whatever you want to see, or pipe into egrep -o '[0-9]+' | head -1 for use with ps -Fp <pid> for that process's info.

The $ lsof <filename> answer by @fin is the best answer, obviously, but to answer @JoseLSegura’s comment, if this isn't available, the solution above was my response.

2

I found that using the accepted answer didn't list the processes that were using my directory ( ubuntu 14.04 ).

In the end, I used lsof (list open files) and grepped its output to find the offending process:

lsof | egrep "<regexp-for-your-file>"
Eosis
  • 121