Given file path, how can I determine which process creates it (and/or reads/writes to it)?
5 Answers
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
.
-
1From 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.– pukSep 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– pukSep 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..– sandricFeb 26, 2015 at 3:29
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.
-
2Suggesting 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 (seeinotifywait
) and better better ways to audit file system access (see Gilles answer).– CalebMay 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.– jcollumApr 6, 2018 at 21:40
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.
-
If the output (or lack of it) of
lsof
is to be believed and my understanding is correct,less
opens a file butemacs
does not. Strange. May 25, 2011 at 19:12 -
7I 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
-
-
-
3Lukasz is correct; if you use
inotify -m /tmp/file
you can see that bothvim
andnano
open, read/write to the file and close it immediately. May 26, 2011 at 0:43
lsof |grep (filename)
This will show you the process that is currently using the file.
-
There is no need for
grep
here. You can givelsof
and argument of a specific filename to query and save a lot of time.– CalebMay 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 :)– MatthewMay 26, 2011 at 13:16
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
inotifywait $file ; lsof -r1 $file
, though. It's much better than runningwhile
loops or usingwatch
.lsof
runs the file may already have been closed.