81

Given file path, how can I determine which process creates it (and/or reads/writes to it)?

3
  • 1
    I thought one of the inotify_tools (inotifywatch or inotifywait) would do this kind of thing. These tools are great if you want to know when a filesystem event happens, but it doesn't look like you can get a pid from inotify.
    – Mark Drago
    May 25, 2011 at 18:31
  • 1
    You could do inotifywait $file ; lsof -r1 $file, though. It's much better than running while loops or using watch. May 26, 2011 at 0:39
  • 4
    The problem is that by the time the lsof runs the file may already have been closed. Apr 15, 2015 at 17:23

5 Answers 5

104

The lsof command (already mentioned in several answers) will tell you what process has a file open at the time you run it. lsof is available for just about every unix variant.

lsof /path/to/file

lsof won't tell you about file that were opened two microseconds ago and closed one microsecond ago. If you need to watch a particular file and react when it is accessed, you need different tools.

If you can plan a little in advance, you can put the file on a LoggedFS filesystem. LoggedFS is a FUSE stacked filesystem that logs all accesses to files in a hierarchy. The logging parameters are highly configurable. FUSE is available on all major unices. You'll want to log accesses to the directory where the file is created. Start with the provided sample configuration file and tweak it according to this guide.

loggedfs -l /path/to/log_file -c /path/to/config.xml /path/to/directory
tail -f /path/to/log_file

Many unices offer other monitoring facilities. Under Linux, you can use the relatively new audit subsystem. There isn't much literature about it (but more than about loggedfs); you can start with this tutorial or a few examples or just with the auditctl man page. Here, it should be enough to make sure the daemon is started, then run auditctl:

auditctl -w /path/to/file

(I think older systems need auditctl -a exit,always -w /path/to/file) and watch the logs in /var/log/audit/audit.log.

4
  • 1
    From my understanding, LoggedFS and audit are like inotify in that they log the information. With something like vim's write feature, first foo.txt.swp is CREATED, then it is MOVED_TO foo.txt. This is logged (I use inotify), but the problem I now have is that when I am reviewing the logs, more often than not, I can no longer stat the foo.txt.swp file. This is creating a great deal of problems for me as the file may be deleted before the DELETE event is logged, so I try to get the file info and the OS complains the file no longer exists.
    – puk
    Sep 1, 2012 at 15:45
  • 1
    @puk This question was about logging, not about reacting to the operation. That would be a different question. OpenBSD's systrace is the leader here, though I think Linux has other things to offer. Sep 2, 2012 at 11:57
  • I doubt I will find what I am looking for: callbacks for system operations
    – puk
    Sep 4, 2012 at 19:59
  • loggedFS, is pretty buggy, and it just dumps me sermentation core dumps after some time. And auditfs is enormously slowing my system..
    – sandric
    Feb 26, 2015 at 3:29
14

Well you could run lsof repeatedly, and if you're lucky the culprit will hold the file open long enough for it to show. Ie.:

$ lsof -r1 /path/to/file

or for many files

$ lsof -r1 /path/to/folder/*

This will list all access to the given path at a certain point in time, once per second. This includes listing the PID of the process accessing the file.

If that doesn't work, that is, the file is opened and closed very quickly, which is often the case, I believe you need to look for more elaborate tools. Maybe loggedfs could be something?

Hackland
If the once-per-second lsof won't work, you could of course hack a while-loop that runs lsof repeatedly as fast as possible. Like:

$ while true; do lsof /paht/to/file; done;

Not pretty, but who knows, might just do it.

2
  • 2
    Suggesting running while true on a tool that doesn't give the right answer anyway isn't a great way to help a new unix user. There are better ways to trigger an action on a file create (see inotifywait) and better better ways to audit file system access (see Gilles answer).
    – Caleb
    May 26, 2011 at 12:32
  • I tried your while suggestion on a file (bash on mac). Edited the file and saved it. lsof never showed anything.
    – jcollum
    Apr 6, 2018 at 21:40
1

You can use lsof for that:

$ lsof /tmp/file
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
less      4737 wena    4r   REG    8,6    90700 1643536 /tmp/file

It says the process named less is the keeping the file "/tmp/file" open.

NOTE: Strangely, that doesn't work if I use geany or nano. Am looking forward to better suggestions.

6
  • If the output (or lack of it) of lsof is to be believed and my understanding is correct, less opens a file but emacs does not. Strange. May 25, 2011 at 19:12
  • 7
    I think that editors just open and read the file to the memory and close it. After that they only monitor file for changes (like vim). May 25, 2011 at 19:27
  • The column that says r would be different if it were writing it.
    – Random832
    May 25, 2011 at 20:04
  • @Random832: thanks for the correction.
    – tshepang
    May 25, 2011 at 21:46
  • 3
    Lukasz is correct; if you use inotify -m /tmp/file you can see that both vim and nano open, read/write to the file and close it immediately. May 26, 2011 at 0:43
0
lsof |grep (filename)

This will show you the process that is currently using the file.

2
  • There is no need for grep here. You can give lsof and argument of a specific filename to query and save a lot of time.
    – Caleb
    May 26, 2011 at 12:35
  • Ah cool to know. Honestly I only ever use it for finding open sockets so I don't really use it for actual files that much. Thanks for the heads up :)
    – Matthew
    May 26, 2011 at 13:16
0

You can use ls and grep to find out the files used by chrome

$ ls -l /proc/*/fd | grep "chrome"
lrwx------ 1 ba abc 64 Jul 16 22:19 104 -> /home/abc/.config/google-chrome/Default/Cookies
lr-x------ 1 abc abc 64 Jul 16 22:19 113 -> /opt/google/chrome/nacl_irt_x86_64.nexe
lrwx------ 1 abc abc 64 Jul 16 22:19 121 -> /home/abc/.cache/google-chrome/Default/Cache/data_0
lrwx------ 1 abc abc 64 Jul 16 22:19 122 -> /home/abc/.cache/google-chrome/Default/Cache/data_1
lrwx------ 1 abc abc 64 Jul 16 22:19 123 -> /home/abc/.cache/google-chrome/Default/Cache/data_2
lr-x------ 1 abc abc 64 Jul 16 22:19 125 -> /home/abc/.config/google-chrome/Dictionaries/en-US-3-0.bdic

Another way is to use lsof and grep

$ lsof | grep "chrome"
chrome     2204       abc  cwd       DIR                8,5     4096 1441794 /home/abc
chrome     2204       abc  rtd       DIR                8,5     4096       2 /
chrome     2204       abc  txt       REG                8,5 87345336 5111885 /opt/google/chrome/chrome
chrome     2204       abc  mem       REG                8,5  4202496 1443927 /home/abc/.cache/google-chrome/Default/Media Cache/data_3
chrome     2204       abc  mem       REG                8,5  1056768 1443926 /home/abc/.cache/google-chrome/Default/Media Cache/data_2
chrome     2204       abc  mem       REG                8,5   270336 1443925 /home/abc/.cache/google-chrome/Default/Media Cache/data_1
chrome     2204       abc  mem       REG                8,5    45056 1443924 /home/abc/.cache/google-chrome/Default/Media Cache/data_0

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