How can I determine what process has a file open in Linux?

127

30

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.

Danny

Posted 2010-01-19T16:08:15.797

Reputation: 1 474

Answers

56

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

Nathan Fellman

Posted 2010-01-19T16:08:15.797

Reputation: 8 152

2fuser 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 – 2014-12-11T10:01:42.330

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). – Scott – 2016-11-16T00:48:32.547

this was great, but to use it in a script i had to check the output length. – chovy – 2013-08-21T07:39:39.680

what do you mean the output length? – Nathan Fellman – 2013-08-21T08:40:12.903

if [fuser "$file"]; then exit – chovy – 2013-08-21T09:05:30.927

146

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:~$

fin

Posted 2010-01-19T16:08:15.797

Reputation: 1 806

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. – Michael Scheper – 2015-12-10T00:48:49.797

this doesn't seem to work for files, only for dirs – Jason – 2019-04-28T04:29:04.730

@Jason: it does work for files, but cwd lines (which report use as the current working directory of a process) only report directories. – reinierpost – 2019-10-07T16:07:06.663

4And what if you don't have lsof? – JoseLSegura – 2014-01-09T11:54:16.550

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

Posted 2010-01-19T16:08:15.797

Reputation: 642

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. – polkovnikov.ph – 2018-03-13T20:24:44.623

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. – Sopalajo de Arrierez – 2014-04-09T21:23:56.177

6

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.

user446020

Posted 2010-01-19T16:08:15.797

Reputation:

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

Posted 2010-01-19T16:08:15.797

Reputation: 121

A more cleaner and faster way for this usage of lsof is its option -R. e.g.:
lsof -R [filename]
– tron5 – 2019-05-24T07:05:00.390