- How to use the Linux ‘lsof’ command to list open files
- Linux lsof command background
- I assume you’re logged in as root
- Basic Linux lsof command examples
- Common lsof options
- Summary: Linux lsof examples
- How to list the open file descriptors (and the files they refer to) in my current bash session
- 5 Answers 5
- Linux — How to track all files accessed by a process?
- 4 Answers 4
- lsof :
- strace :
How to use the Linux ‘lsof’ command to list open files
Linux “open files” FAQ: Can you share some examples of how to show open files on a Linux system — i.e., how to use the lsof command?
Linux lsof command background
The Linux lsof command lists information about files that are open by processes running on the system. The lsof command is an acronym for, “list of open files.” In this article I’ll share some lsof command examples.
I assume you’re logged in as root
One other note: In these examples I’ll assume that you’re logged in as the Unix/Linux root user. If not, you’re lsof command output may be significantly limited. If you’re logged in as a non-root user, either su to root, or use sudo to run these commands.
Basic Linux lsof command examples
Typing the lsof command by itself lists all open files belonging to all active processes on the system:
On my current macOS system, which has been running for a long time, this shows a lot of open files, 1,582 to be specific:
$ lsof | wc -l 1582
Note that I didn’t have to be logged in as the root user to see this information on my Mac system.
Adding the head command to lsof shows what some of this output looks like:
$ lsof | head COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME loginwind 32 Al cwd DIR 14,2 1564 2 / loginwind 32 Al txt REG 14,2 1754096 243026930 /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow loginwind 32 Al txt REG 14,2 113744 3190067 /System/Library/LoginPlugins/FSDisconnect.loginPlugin/Contents/MacOS/FSDisconnect loginwind 32 Al txt REG 14,2 425504 117920371 /System/Library/LoginPlugins/DisplayServices.loginPlugin/Contents/MacOS/DisplayServices loginwind 32 Al txt REG 14,2 3144 3161654 /System/Library/ColorSync/Profiles/sRGB Profile.icc loginwind 32 Al txt REG 14,2 96704 242998403 /System/Library/PrivateFrameworks/MachineSettings.framework/Versions/A/MachineSettings loginwind 32 Al txt REG 14,2 51288 251253153 /private/var/folders/h5/h59HESVvEmG+3I4Q8lOAxE+++TI/-Caches-/mds/mdsDirectory.db loginwind 32 Al txt REG 14,2 724688 117923285 /System/Library/LoginPlugins/BezelServices.loginPlugin/Contents/MacOS/BezelServices loginwind 32 Al txt REG 14,2 329376 117923166 /System/Library/Extensions/IOHIDFamily.kext/Contents/PlugIns/IOHIDLib.plugin/Contents/MacOS/IOHIDLib
Common lsof options
As mentioned, these details go on for 1,582 lines, so it helps to have some way to weed through that output, whether that involves using the grep command, or some of the lsof options shown below.
This command lists all open files belonging to PID (process ID) 11925 :
$ lsof -p 11925
This command lists all open files belonging to processes owned by the user named «al»:
This command lists files that are open in the directory specified, but it does not descend into sub-directories:
$ lsof +d '/Users/al'
The next command lists files that are open in the directory specified, and also descends into sub-directories. Beware: this can take a very long time to run for large directory structures:
$ lsof +D '/Users/al'
Summary: Linux lsof examples
I hope these Linux lsof command examples have been helpful. As you can see, the lsof command can be used to generate a list of open files on your Unix and Linux system with a variety of different command line options for different circumstances.
For more information on the lsof command, please see the «Related» block on this page, follow this link to lsof command search results on this website, or leave a note in the Comments section below.
How to list the open file descriptors (and the files they refer to) in my current bash session
I am running in an interactive bash session. I have created some file descriptors, using exec, and I would like to list what is the current status of my bash session. Is there a way to list the currently open file descriptors?
bash is not part of the kernel, so it can not know what other processes are doing, even those that it started.
@JuliePelletier: but child processes do not change the file descriptors of the parent process, do they?
5 Answers 5
Yes, this will list all open file descriptors:
$ ls -l /proc/$$/fd total 0 lrwx------ 1 isaac isaac 64 Dec 28 00:56 0 -> /dev/pts/6 lrwx------ 1 isaac isaac 64 Dec 28 00:56 1 -> /dev/pts/6 lrwx------ 1 isaac isaac 64 Dec 28 00:56 2 -> /dev/pts/6 lrwx------ 1 isaac isaac 64 Dec 28 00:56 255 -> /dev/pts/6 l-wx------ 1 isaac isaac 64 Dec 28 00:56 4 -> /home/isaac/testfile.txt
Of course, as usual: 0 is stdin, 1 is stdout and 2 is stderr.
The 4th is an open file (to write) in this case.
@JZ. $$ will give the process ID of the currently running shell. Try echo $$ and ps and compare their outputs. Similar question here.
Assuming you want to list the file descriptors that are attached to any terminal, you can use lsof / fuser or similar like:
$ lsof -p $$ 2>/dev/null | awk '$NF ~ /\/pts\//' bash 32406 foobar 0u CHR 136,31 0t0 34 /dev/pts/31 bash 32406 foobar 1u CHR 136,31 0t0 34 /dev/pts/31 bash 32406 foobar 2u CHR 136,31 0t0 34 /dev/pts/31 bash 32406 foobar 3u CHR 136,31 0t0 34 /dev/pts/31 bash 32406 foobar 255u CHR 136,31 0t0 34 /dev/pts/31
These tools basically parse /proc , so you can just access /proc/$$/fd/ too e.g.:
Use the lsof utility to print all file descriptors for the current shell process (process identified by -p $$ ) and ( -a ) where the file descriptor is numeric ( -d 0-256 ):
$ lsof -p $$ -a -d 0-256 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 16883 ant 0u CHR 136,15 0t0 18 /dev/pts/15 bash 16883 ant 1u CHR 136,15 0t0 18 /dev/pts/15 bash 16883 ant 2u CHR 136,15 0t0 18 /dev/pts/15 bash 16883 ant 255u CHR 136,15 0t0 18 /dev/pts/15
Pipe into Awk to print only the file descriptor and its corresponding filename:
$ lsof -p $$ -a -d 0-256 | awk '< printf("%4s:\t%s\n", $4, $NF) >' FD: NAME 0u: /dev/pts/15 1u: /dev/pts/15 2u: /dev/pts/15 255u: /dev/pts/15
Note: when lsof prints the file descriptors, it appends the following code to indicate the file access mode:
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.