140

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.

5 Answers 5

70

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
7
  • this was great, but to use it in a script i had to check the output length.
    – chovy
    Aug 21, 2013 at 7:39
  • what do you mean the output length? Aug 21, 2013 at 8:40
  • if [ fuser "$file"` ]; then exit`
    – chovy
    Aug 21, 2013 at 9:05
  • 2
    fuser has strange behavior with exit codes. it returns 1 exitcode with two states: A/ some internal error, checked file not found etc, B/ no process opened specified file. In situation A/ some error message is printed to its output. Unfortunately when file is available and opened by something, output is generated but with exit code 0. It would be better if fuser will exit with three codes, not two like currently. lsoft is a bit worse resolve because this is working more slowly.
    – Znik
    Dec 11, 2014 at 10:01
  • This is essentially the same pattern that ls follows — it returns exit code 2 if there's an error (e.g., invalid option specified) or file not found (and 0 if it successfully reports information). Nov 16, 2016 at 0:48
154

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:~$
4
  • 4
    And what if you don't have lsof? Jan 9, 2014 at 11:54
  • 3
    @JoseLSegura: I assuming you're resourceful enough for the answer 'then install lsof' to be useless for you. Can you elaborate on your problem? If you don't have root, you likely don't have privs to find out if another user has the file open anyhow. Dec 10, 2015 at 0:48
  • this doesn't seem to work for files, only for dirs
    – Jason
    Apr 28, 2019 at 4:29
  • @Jason: it does work for files, but cwd lines (which report use as the current working directory of a process) only report directories. Oct 7, 2019 at 16:07
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$'

2
  • the `ls -l' method works for Linux but seems not to be working for CygWin: there is no info about file locking there. Wouldn't you know how to solve? Thanks. Apr 9, 2014 at 21:23
  • No, you don't create read-only file for a lock, because when your app will crash, the file will still be there. Forcing user to clear up the crap after your crashed app is mental. Mar 13, 2018 at 20:24
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.

1
  • This is exactly what I was looking for. But why does this return 1 always?
    – Sam Thomas
    Apr 6, 2020 at 20:45
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>"
1
  • 2
    A more cleaner and faster way for this usage of lsof is its option -R. e.g.: lsof -R [filename]
    – tron5
    May 24, 2019 at 7:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .