LSOF: List the Open Files

Linux Apr 16, 2026

lsof is a small and interesting utility that is able of finding all the open files in our Linux system. We need to bear in mind that for Linux everything is a file - According to lsof man page:

An open file may be a regular file, a directory, a block special file, a character special file, an executing text reference, a library, a stream or a network file (Internet socket, NFS file or UNIX domain socket.) A specific file or all the files in a file system may be selected by path.

Note that lsof sometimes shows some output in stderr (specially regarding overlay filesystems as the ones used by docker). So it is quite convenient to redirect all the err output to /dev/null.

Opened regular files.

This is the basic thing we can do with lsof. There are 2 main questions here. On the one hand, we can query about a file or directory - What process and user id has opened a file or have files opened in a given directory

## This one tells what process is using the file
lsof <file>

## What process/users have files opened in the directory
lsof +D <dir>

On the other hand, we can query what files has opened an user or a process

# Files opened by an user
lsof -u <user>

# Files opened by a process PID
lsof -p <pid>

Understanding lsof output

lsof will show the output with the following fileds as shown in the header:

COMMAND   PID USER  FD      TYPE   DEVICE  SIZE/OFF       NODE NAME
  • Command - The command typed. It can be zsh, lsof, vim, ...
  • PID - The process ID which opened a file.
  • USER - The name of the user which opened the file
  • FD - File Descriptor - This one shows the file descriptor in the process and the mode that it is opened:
    • 0 - stdin
    • 1- stdout
    • 2 - stderr
    • n - File number, usually you'll find some letters referencing the permissions:
      • r read, w write, u update (read and write)
  • TYPE - Type of file. It doesn't have to be something in the hard disk. There are many different file types.
    • cwd - Current working directory.
    • rtd - Root directory (Where the process was started)
    • txt - Text file. This is usually the program binary file.
    • mem - Memory mapped file (usually dynamic libraries)
    • REG- Regular file
    • DIR- Directory
    • CHR - This is a special fie of type character (e.g. /dev/tty, /dev/pts/0)
    • FIFO - Pipe for interprocess communication.
    • UNIX - UNIX domain socket.
    • IPv4/IPv6 - Network connection.
    • DEL - These files are usually not in the disk but they are usually in shared memory /dev/shm (e.g. brave browser) or files only existing in memory but not in the disk (/memfd:pulseaudio).
# Example: CHR files used by my zsh shell
❯ lsof -p 17062 2>/dev/null | grep CHR
zsh     17062 jicg   0u   CHR  136,0      0t0         3 /dev/pts/0
zsh     17062 jicg   1u   CHR  136,0      0t0         3 /dev/pts/0
zsh     17062 jicg   2u   CHR  136,0      0t0         3 /dev/pts/0
zsh     17062 jicg  10u   CHR  136,0      0t0         3 /dev/pts/0
  • DEVICE - It shows minor and mayor numbers of the device. It identifies the device or device partition where the file is stored
# And following my previous example, where we had the device with values
# 136,0 -- So I can list those devices in /dev: 
# The devuce /dev/pts corresponds to 0, 1, 2 (stdin, stdout and stderr).
❯ ls -l /dev/pts | grep 136
crw--w---- 1 jicg tty  136, 0 abr 16 10:30 0
crw--w---- 1 jicg tty  136, 1 abr 16 10:05 1
crw--w---- 1 jicg tty  136, 2 abr 16 10:30 2

# Another one I usually see in my testing is 253,0 - My nvme device.
❯ ls -l /dev/ | grep 253
brw-rw----   1 root disk      253,     0 abr 16 09:52 dm-0
  • SIZE/OFF - For regular files, this one shows the size of the file and the OFFSET pointer in the process.
  • NODE - This one is the inode, basically a number representing the inode of the regular file, or if we are waching the sockets, it can show the protocol (TCP/UDP), etc.
  • NAME - The name (descriptive name) or what is it opened. It can be a name of a file, it can be an ip address/port if we are watching the network connections.

Deleted files

Sometimes, we can find "deleted" files, this means that a file has been deleted but the process which opened it still haven't closed it. This file will disappear when the process closes it or when the process dies.

tcpdump port 143 -w /tmp/f.pcap & 

rm /tmp/f.pcap

# We can see the process now ant the deleted mark
lsof -p 390635 2>/dev/null | grep deleted
tcpdump 390635 root   5w      REG   0,36        0     10619 /tmp/f.pcap (deleted)

We know that in Linux the name of the file (a tag in a directory) and the file are separated. Linux will only remove the file content when:

  • It is not pointed by any name (link).
  • No process keeps it open.

Zombie file - Are deleted files still opened by a process, it might be weird but it has some useful usecases:

  • Updating libraries (.so) while a program is still running. The file is removed from disk, but as the original library file is still opened, the file is not still removed from disk. The process can continue running.
  • Security and privacy - Sometimes a file is created and removed from disk so it can't be seen with a single ls command.

So, sometimes, you need to be aware that if you remove a huge log file because you are running out of disk space, this space will not be freed until the process is restarted.

Sockets and network connections

We can also watch for opened network connections using lsof - From Linux perspective sockets have their own file descriptor and this means that they are treated as opened files.

We can see these network connections using lsof -i - for TCP or UDP sockets

# watch connections (opened port)
#    lsof -i [:port]  --- 
#
#  -n (-n prevents name resolition - DNS - Shows only IP)
#  -P (-P prevents converting ports to protocol names)

❯ sudo lsof -i :22
COMMAND PID USER FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    964 root 6u  IPv4   9690      0t0  TCP *:ssh (LISTEN)
sshd    964 root 7u  IPv6   9692      0t0  TCP *:ssh (LISTEN)
❯ sudo lsof -Pi :22
COMMAND PID USER FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    964 root 6u  IPv4   9690      0t0  TCP *:22 (LISTEN)
sshd    964 root 7u  IPv6   9692      0t0  TCP *:22 (LISTEN)

We can see UNIX sockets using lsof -U.

There is much more regarding the parameter -i -

# List all TCP sockets in LISTEN state:
sudo lsof -iTCP -sTCP:LISTEN -n -P

# List UDP sockets
sudo lsof -iUDP -n -P

# Listar all TCP and UDP sockets
sudo lsof -i -n -P

So, the information shown by lsof could also be used to have a good grasp of what ports are opened in our system and the connections in our system. It is not as complete as ss output, but it is quite valuable.

Tags