- Linux — How to track all files accessed by a process?
- 4 Answers 4
- lsof :
- strace :
- Use of “lsof” Command to Find Open Files
- Use of “lsof” Command to Find the Open Files in Linux Mint 20
- Conclusion
- About the author
- Karim Buzdar
- 7 Examples of lsof command in Linux
- lsof command examples
- 1. List all the processes that have opened a certain file
- 2. List all the files opened by user
- 3. List all opened files in a directory
- 4. List all opened files by a process
- 5. List all files opened by a command
- 6. Find files opened by a user and a command or a process
- 7. List network connections and ports with lsof command
- Bonus Tip: Using the negation operator with lsof
Linux — How to track all files accessed by a process?
Is there a way to track all file I/O for a given process? All I really need is the locations of files being read from/written to from a given process (and ideally if it was a read or write operation although that’s not as important). I can run the process and track it rather than needing to attach to an existing process which I would assume is significantly simpler. Is there any kind of wrapper utility I can run a process though that will monitor file access?
4 Answers 4
lsof :
Try doing this as a starter :
this command will list all currently open files, fd, sockets for the process with the passed process ID.
For your special needs, see what I can offer as a solution to monitor a php script :
php foo.php & _pid=$! lsof -r1 -p $_pid kill %1 # if you want to kill php script
strace :
I recommend the use of strace . Unlike lsof , it stays running for as long as the process is running. It will print out which syscalls are being called when they are called. -e trace=file filters only for syscalls that access the filesystem:
sudo strace -f -t -e trace=file php foo.php
or for an already running process :
sudo strace -f -t -e trace=file -p
Thanks that’s a good starting point! It works for processes already running at the moment it’s run. I’m trying to do this for a PHP script for its entire execution, tracking the files from the start of the process until it exists. Looking at the help, There’s a -r repeat option but this seems to periodically scan the files that are open by the process rather than have been opened. Essentially I want to do this: lsof -p $$ && exec php foo.php This doesn’t seem to list files that are opened by foo.php
thanks, that’s certainly providing more relevant information and showing all the php extensions being loaded, the script contains unfortunately, file.txt is not listed in the output. I can verify the file is being opened by amending the script to print the contents of file.txt but I still don’t see file.txt in the output of lsof.?php>
To properly trace an AppImage, I needed to run strace as root but the command using my own user. This got the job done: sudo strace -fte trace=%file -u $(id -un)
Mixing your two solutions together becomes perfect: php foo.php & sudo strace -f -t -e trace=file -p $! especially for short running tasks.
Besides strace there is another option which does not substantially slow down the monitored process. Using the Liunx kernel’s fanotify (not to be confused with the more popular inotify) it is possible to monitor whole mount-points for IO-activity. With unshared mountnamespaces the mounts of a given process can be isolated fromt the rest of the system (a key technology behind docker).
An implementation of this concept can be found in shournal, which I am the author of.
$ shournal -e sh -c 'cat foo > bar' $ shournal --query --history 1 . 1 written file(s): /home/user/bar 1 read file(s): /home/user/foo
External links are always highly appreciated as sources, but imagine this one was to become invalid — your solution would be unsalvageable for future SO users. Please consider posting code here and explaining your solution so we all can learn.
@harmonica141: That’s always the problem: what to write and what to omit. A complete, minimal example would be not much shorter than the example at the bottom at man7.org/linux/man-pages/man7/fanotify.7.html . In fact, it could be almost the same with a leading unshare( CLONE_NEWNS); . Do you think it would be helpful to include the full source here?
strace is an amazing tool but its output is a bit verbose.
If you want you can use a tool I’ve written which processes strace output and provide a CSV report of all files accessed (TCP sockets too) with the following data:
1. Filename
2. Read/Written bytes
3. Number of read/write operations
4. Number of time the file was opened
It can be run on new processes or processes already running (using /proc/fd data).
I found it useful for debugging scenarios and performance analysis.
You can find it here: iotrace
Filename, Read bytes, Written bytes, Opened, Read op, Write op /dev/pts/1,1,526512,0,1,8904 socket_127.0.0.1:47948->127.0.0.1:22,1781764,396,0,8905,11 myfile.txt,65,0,9,10,0 pipe:[3339],0,0,0,1,0
Afterward, you can process the CSV data in Excel or other tools for sorting or other analysis required.
The downside is you need to download & compile and it isn’t always 100% accurate.
Use of “lsof” Command to Find Open Files
“lsof” stands for List Open Files. It is a Linux utility for listing down all the open files of a system. This command can be combined with different parameters to modify its output as desired. You can see the details of all of its parameters and flags by seeing the help manual of the “lsof” command.
In today’s article, you will be able to learn the correct usage of the “lsof” command for finding all the open files in Linux Mint 20.
Use of “lsof” Command to Find the Open Files in Linux Mint 20
To learn the correct usage of the “lsof” command and use it to find the open files in Linux Mint 20, you can take a look at all the examples that have been shared below.
Example 1: List All the Open Files in Linux Mint 20
To list down all the open files in Linux Mint 20, you will have to execute the following command in the terminal:
This command will display a list of all the currently opened files on your Linux Mint 20 system, as shown in the image below:
Example 2: List All the Open Files Belonging to a Particular Directory in Linux Mint 20
You can also list down all the open files belonging to a particular directory in Linux Mint 20 by specifying the name of that directory with the “lsof” command in the following manner:
Here, you have to replace the directorypath with the actual path of the directory whose open files you want to list down. For example, we have replaced it with “/var/log/”.
This command will display a list of all the open files that belong to the “/var/log/” directory, as shown in the image below:
Example 3: List All the Open Files Belonging to a Particular User in Linux Mint 20
If you want to list down all the open files belonging to a particular user in Linux Mint 20, then you can do so by executing the “lsof” command in the following manner:
Here, you have to replace the username with the name of the user whose open files you want to list down. For example, we have replaced it with “kbuzdar”.
This command will display a list of all the open files that belong to the specified user, as shown in the image below:
Example 4: List All the Open Files Belonging to a Particular Internet Protocol in Linux Mint 20
You can also try to list down all the open files belonging to a particular Internet protocol in Linux Mint 20 by executing the “lsof” command in the following manner:
You can also replace “6” with “4” if you want to list down all the open files belonging to IPv4.
This command will display a list of all the open files belonging to the IPv6 protocol, as shown in the image below:
Example 5: List All the Open Files Belonging to a Particular File System in Linux Mint 20
If you want to list down all the open files belonging to a particular file system in Linux Mint 20, then you can do so by tweaking the “lsof” command in the following manner:
Here, you can replace “/proc” with any other file system of your choice as well.
This command will display a list of all the open files belonging to the “/proc” file system, as shown in the image below:
Conclusion
By going through all the examples that have been shown to you in this article, you will be able to learn the correct usage of the “lsof” command for finding all the open files in Linux Mint 20.
About the author
Karim Buzdar
Karim Buzdar holds a degree in telecommunication engineering and holds several sysadmin certifications. As an IT engineer and technical author, he writes for various web sites. He blogs at LinuxWays.
7 Examples of lsof command in Linux
I guess at some point in time you have wondered if there is a way to show opened files by a process or a user. The good thing is that the answer to that question is lsof command.
You probably already know that ls command is short for ‘list’. lsof stands for ‘List Open Files’. And that’s exactly what it does, listing open files by processes, users, and process IDs.
Let me show you some of the most common usages of the lsof command.
lsof command examples
If you use lsof command without any options and arguments, it will list all opened files by all the processes in the system.
The output should be like this:
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root cwd DIR 252,1 4096 2 / systemd 1 root rtd DIR 252,1 4096 2 / systemd 1 root txt REG 252,1 1595792 17384 /lib/systemd/systemd systemd 1 root mem REG 252,1 1700792 2077 /lib/x86_64-linux-gnu/libm-2.27.so
The output is mostly self-explanatory but you may still wonder about FD and TYPE columns.
FD means file descriptor. Some of the common values for FD are:
- cwd – Current Working Directory
- txt – Text files
- mem – Memory mapped file
- mmap – Memory mapped device
- NUMBER – The actual file descriptor. It also has information about which file permission it is opened in.
TYPE is a no-brainer. It specifies the file type. Here are some examples:
- REG – Regular file
- DIR – Directory
- CHR – Character special file
- FIFO – First In First Out
Trust me. You wouldn’t want to run the lsof command without any arguments.
Why do I say this? Because it will start flooding your screen with thousands of results.
If I run the lsof command on an Ubuntu server and count the number of lines with wc command, here’s the result.
Yes! That’s right. There are over eleven thousand files opened by various processes in the system.
Don’t worry. lsof command is very helpful in debugging because you can see what processes open what files and which file is opened by which process.
If you are not logged in as root, the output of lsof command would be very limited. It is a good idea to use sudo if you are logged in as a non-root user.
1. List all the processes that have opened a certain file
This is simple. You just need to specify the path to the file.
2. List all the files opened by user
This comes handy in a multi-user environment. You can list all the files opened by a certain user in the following manner:
You can also specify more than one user like this:
3. List all opened files in a directory
If you are wondering which of the files have been opened in a certain directory, you can use lsof command with +D option.
The search is recursive. So it will list all the opened files in the mentioned directory and all of its sub-directories.
4. List all opened files by a process
You need to know the process id (pid) in this case. If you know the process id, you can use the -p option of the lsof command to find the files opened by it.
You can specify multiple process ids as well.
5. List all files opened by a command
This is specially helpful in debugging. Suppose you want to see what files are used by http daemon, you just need to specify the command name (httpd in our example).
6. Find files opened by a user and a command or a process
You can combine options like user and command and a process using the –a option. Think of it as the AND operator. This gives you an additional filter while trying to narrow down on your search.
lsof -a -u user_name -c command_name
7. List network connections and ports with lsof command
You can file all kinds of open ports with the -i option:
The output may look like this:
lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 920 root 3u IPv4 20507 0t0 TCP *:ssh (LISTEN) sshd 920 root 4u IPv6 20535 0t0 TCP *:ssh (LISTEN) docker-pr 1163 root 4u IPv6 21687 0t0 TCP *:https (LISTEN) docker-pr 1175 root 4u IPv6 21717 0t0 TCP *:http (LISTEN) sshd 7528 root 3u IPv4 39506588 0t0 TCP testing:ssh->212.91.91.19:58904 (ESTABLISHED) systemd-r 10993 systemd-resolve 12u IPv4 20901990 0t0 UDP localhost:domain systemd-r 10993 systemd-resolve 13u IPv4 20901991 0t0 TCP localhost:domain (LISTEN)
You can also specify the network connection type. For example, to list all the opened TCP ports, you can use:
To find which process is using a specific port, you can provide the port number:
Bonus Tip: Using the negation operator with lsof
You can use the negation operator to exclude a user or process while using lsof command.
For example, if you want to list all the files opened by a user other than root, use it in this manner:
lsof command becomes even more useful when you use it with the grep command.
I hope you learned something new from this article. If you have questions or suggestions, please leave a comment below.