On Linux, Everything Is a File
The oft-quoted phrase that everything in Linux is a file is sort of true. A file is a collection of bytes. When they are being read into a program or sent to a printer, they appear to generate a stream of bytes. When they are being written to, they accept a stream of bytes.
Many other system components accept or generate streams of bytes, such as keyboards, socket connections, printers, and communication processes. Because they either accept, generate, or accept and generate byte streams, these devices can be handled—at a very low level—as though they were files.
This design concept simplified the implementation of the Unix operating system. It meant that a small set of handlers, tools, and APIs could be created to handle a wide range of different resources.
The data and program files that reside on your hard disk are plain old filesystem files. We can use the ls command to list them and find out some details about them.
How do we find out about all the other processes and devices that are being treated as though they were files? We use the lsof command. This lists the open files in the system. That is, it lists anything that is being handled as though it were a file.
RELATED: What Does “Everything Is a File” Mean in Linux?
The lsof Command
Many of the processes or devices that lsof can report on belong to root or were launched by root, so you will need to use the sudo command with lsof.
And because this listing will be very long, we are going to pipe it through less .
Before the lsof output appears GNOME users may see a warning message in the terminal window.
lsof tries to process all mounted filesystems. This warning message is raised because lsof has encountered a GNOME Virtual file system (GVFS). This is a special case of a filesystem in user space (FUSE). It acts as a bridge between GNOME, its APIs and the kernel. No one—not even root—can access one of these file systems, apart from the owner who mounted it (in this case, GNOME). You can ignore this warning.
The output from lsof is very wide. The leftmost columns are:
The rightmost columns are:
The lsof Columns
All columns do not apply to every type of open file. It is normal for some of them to be blank.
Command: The name of the command associated with the process that opened the file. PID: Process Identification number of the process that opened the file. TID: Task (thread) Identification number. A blank column means it is not a task; it is a process. User: User ID or name of the user to whom the process belongs, or the user ID or login of the person that owns the directory in /proc where lsof finds information about the process. FD: Shows the file descriptor of the file. File descriptors are described below. Type: type of node associated with the file. Note types are described below. Device: Contains either the device numbers, separated by commas, for a character special, block special, regular, directory or NFS file, or a kernel reference address that identifies the file. It might also show the base address or device name of a Linux AX. 25 socket device. Size/Off: Shows the size of the file or the file offset in bytes. Node: Shows the node number of a local file, or the inode number of an NFS file in the server host, or internet protocol type. It might display STR for a stream or the IRQ or inode number of a Linux AX. 25 socket device. Name: Shows the name of the mount point and file system on which the file resides.
The FD Column
The file descriptor in the FD column can be one of many options; the man page list them all.
The FD column entry can be made up of three parts: a file descriptor, a mode character, and a lock character. Some common file descriptors are:
cwd: Current working directory. err: FD information error (see NAME column). ltx: Shared library text (code and data). m86: DOS Merge mapped file. mem: Memory-mapped file. mmap: Memory-mapped device. pd: Parent directory. rtd: Root directory. txt: Program text (code and data) A number, representing a file descriptor.
The mode character can be one of the following:
r: Read access. w: Write access. u: Read and Write access. ‘ ‘: A space character, if the mode is unknown and there is no lock character. –: Mode unknown and there is a lock character.
The lock character can be one of:
r: Read lock on part of the file. R: Read lock on the entire file. w: Write lock on part of the file. W: Write lock on the entire file. u: Read and write lock of any length. U: Unknown lock type. ‘ ‘: A space character. No lock.
The TYPE Column
There are over 70 entries that might appear in the TYPE column. Some common entries you will see are:
REG: Regular filesystem file. DIR: Directory. FIFO: First In First Out. CHR: Character special file. BLK: Block special file. INET: Internet socket. unix: UNIX domain socket
See Processes That Have Opened a File
To see the processes that have opened a certain file, provide the name of the file as a parameter to lsof. For example, to see the processes that have opened kern.log file, use this command:
lsof responds by displaying the single process, rsyslogd which was started by the user syslog.
See All Files Opened from a Directory
To see the files that have been opened from a directory, and the processes that opened them, pass the directory to lsof as a parameter. You must use the +D (directory) option.
To see all the files that are open in the /var/log/ directory, use this command:
lsof responds with a list of all the open files in that directory.
To see all the files that have been opened from the /home directory, use the following command:
The files have been opened from the /home directory are displayed. Note that with shorter descriptions in some of the columns, the whole listing is narrower.
List Files Opened By a Process
To see the files that have been opened by a particular process, use the -c (command) option. Note that you can provide more than one search term to lsof at once.
lsof provides a list of the files that have been opened by either of the processes provided on the command line.
See Files Opened By a User
To limit the display to the files that have been opened by a specific user, use the -u (user) option. In this example, we’ll look at the files that have been opened by processes that are owned or launched on behalf of Mary.
All of the files listed have been opened on behalf of the user Mary. This includes files that have been opened by the desktop environment, for example, or simply as a result of Mary having logged in.
Excluding FIles Opened by a User
To exclude the files that have been opened by a user, use the ^ operator. Excluding users from the listing makes it easier to find the information you are interested in. You must use the -u option as before, and add the ^ character to the start of the user’s name.
This time, the listing for the /home directory does not include any of the files that have been opened by the user Mary.
List FIles Opened by a Process
To list the files that have been opened by a specific process, use the -p (process) option and provide the process ID as a parameter.
All of the files that have been opened by the process ID you provide are listed for you.
Listing Process IDs That Have Opened a FIle
To see the process IDs for the processes that have opened a particular file, use the -t (terse) option and provide the name of the file on the command line.
The process IDs are displayed in a simple list.
Use AND and OR Searches
Let’s list the files that have been opened by user Mary, that are related to the SSH processes. We know we can provide more than one search item on the command line, so this should be easy.
Now let’s look at the output from lsof. That doesn’t look right; there are entries in the output that were started by root.
That isn’t what we expected. What happened?
When you provide multiple search terms lsof will return any file that matches the first search term or the second search term, and so on. In other words, it performs an OR search.
To make lsof perform an AND search, use the -a (and) option. This means the only files that will be listed will be ones that match the first search term, and the second search term, and so on.
Let’s try that again and use the -a option.
Now every file in the listing is one that has been opened by or on behalf of Mary, and are associated with the SSH command.
Automatically Refreshing The Display
We can use the +|-r (repeat) option to put lsof into repeat mode. The repeat option can be applied in two ways, either +r or -r. We must also add the number of seconds we want lsof to wait before refreshing the display.
Using the repeat option in either format makes lsof display the results as usual, but it adds a dashed line to the bottom of the display. It waits for the number of seconds provided on the command line and then refreshes the display with a new set of results.
With the -r option this will continue until you press Ctrl+C. With the +r format, it will continue until there are no results to display, or until you press Ctrl+C.
Note the dashed line at the bottom of the listing. This separates each new display of data when the output is refreshed.
Displaying Files Associated with Internet Connections
The -i (internet) option allows you to see the files opened by processes associated with network and internet connections.
All of the files opened by network and internet connections are displayed.
Displaying Files Associated with Internet Connections by Process ID
To see the files opened by internet connections that are associated with a specific process ID, add the -p option and the -a option.
Here we are looking for files opened by an internet or network connection, by a process with an ID of 606.
All of the files opened by process ID 606 that are associated with internet or network connections are displayed.
Displaying Files Associated with Internet Connections and Commands
We can use the -c (command) option to look for files opened by specific processes. To look for files that have been opened by internet or network connections associated with the ssh process, use the following command:
All of the files opened due to the ssh processes are listed in the output.
Displaying Files Associated with Internet Connections and Ports
We can make lsof report on the files that were opened by internet or network connections on a specific port. To do this, we use the : character followed by the port number.
Here we’re asking lsof to list the files that have been opened by network or internet connections using port 22.
All of the listed files were opened by processes associated with port 22 (which is the default port for SSH connections).
Displaying Files Associated with Internet Connections and Protocols
We can ask lsof to show the files that have been opened by processes associated with network and internet connections, that are using a specific protocol. We can choose from TCP, UDP, and SMTP. Let’s use the TCP protocol and see what we get.
The only files listed are those opened by processes that are using the TCP protocol.
We’ve Only Scratched the Surface
That’s a good grounding in some common use cases for lsof, but there is a lot more to it than that. Just how much more can be judged by the fact the man page is over 2,800 lines long.
The lsof command can be used to drill ever deeper into the strata of open files and pseudo-files. We’ve provided a sketch map; the atlas is in the man page.