How to Use the lsof Command in Linux to Track Open Files, Active Ports, and Process Sockets

One of the core design philosophies of Unix and Linux operating systems is that “everything is a file.” Beyond regular text documents, binary executables, and filesystem directories, the Linux kernel abstracts network sockets, hardware device drivers (under /dev), pipes, and kernel telemetry pseudofiles (under /proc) as file descriptors. Consequently, when an administrative task fails with “Device or resource busy” during unmounting, or when a web server cannot bind to port 80 because it is already in use, the root cause is almost always an open file descriptor held by an active process.

To inspect active file descriptors across the entire operating system, systems engineers rely on the “list open files” utility: lsof. By querying kernel data structures and process descriptor tables, lsof bridges the gap between running process IDs (PIDs) and filesystem resources. This technical guide covers lsof syntax, network port tracking, locked filesystem release techniques, user filtering, and automated troubleshooting one-liners.

Essential lsof Command Output Columns

Running sudo lsof produces tabular output describing every open handle in the kernel:

Column Header Technical Meaning Diagnostic Function
COMMAND Executable process name. Identifies the software binary holding the handle (e.g., nginx, sshd, python3).
PID Process Identifier. The target process identifier required to gracefully terminate or signal the task.
USER Owning system user. Audits privilege ownership (e.g., root, www-data, postgres).
FD File Descriptor. Indicates handle mode (cwd = current working dir; txt = code; 1u = read/write stream).
TYPE Filesystem node type. Distinguishes regular files (REG), directories (DIR), and sockets (IPv4, IPv6, unix).
NODE / NAME Filesystem inode or path/socket. Displays full directory path, TCP socket endpoint, or listening port.

Step 1: Identifying Which Process is Listening on a Network Port

When starting a container, Node.js app, or Apache service fails because a port is occupied:

Finding the Process on a Specific Port

sudo lsof -i :8080

Example terminal output:

COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    24108   deploy   19u  IPv4 184021      0t0  TCP *:8080 (LISTEN)

Listing All Active Listening Ports (-i -sTCP:LISTEN)

To audit every service currently awaiting inbound connections without resolving IP hostnames (using -n and -P for speed):

sudo lsof -iTCP -sTCP:LISTEN -n -P

Filtering by Established Network Connections

To track live outbound connections established with remote database hosts or external APIs:

sudo lsof -i @192.168.1.100 -n -P

Step 2: Tracking Open Files Within Specific Directories

To audit which processes are reading or writing inside a critical directory tree (e.g., /var/log or /opt/app):

Recursively Scanning a Directory (+D)

sudo lsof +D /var/log/nginx/

Inspecting a Specific File

To find out what application is locking a database file or configuration file:

sudo lsof /var/lib/mysql/ibdata1

Step 3: Resolving “Device or resource busy” on Mount Points

When attempting to unmount an external USB drive, NFS share, or secondary partition (umount /mnt/data), Linux frequently returns “target is busy” if an open shell, daemon, or background process has its working directory or file handles inside that volume:

  1. Query the mount point to find all locking processes:
    sudo lsof +f -- /mnt/data
  2. Review the output: often an administrator has a terminal window whose working directory is /mnt/data/backups (marked as cwd in the FD column).
  3. Navigate out of the directory in the offending shell, or terminate the blocking process using its PID:
    sudo kill -15 <PID>
  4. Once freed, retry unmounting:
    sudo umount /mnt/data

Step 4: Recovering Deleted Files That Are Still Held Open

If an administrator accidentally deletes a multi-gigabyte log or database file with rm, Linux does not immediately free the disk space or erase data blocks if a running process still holds an open file handle:

  1. Locate deleted files that processes are still holding open:
    sudo lsof +L1

    The +L1 flag lists files with a link count of less than 1 (meaning the directory link was unlinked/deleted).

  2. Note the PID and File Descriptor number (e.g., PID 4092, FD 3r).
  3. Recover the entire contents of the deleted file directly from the Linux procfs filesystem:
    sudo cp /proc/4092/fd/3 /tmp/recovered_file.log

Step 5: Filtering by User or Process ID

You can isolate activity by specific users or processes:

# List all open files held by user www-data
sudo lsof -u www-data

# List all open files excluding user root (using the ^ negation operator)
sudo lsof -u ^root

# List all handles owned by process PID 1234
sudo lsof -p 1234

Operational Performance Tips

  • Always Combine with -n and -P: Omitting -n (disable DNS) and -P (disable port name mapping) forces lsof to execute network lookups for every socket, causing long terminal freezes on busy networks. Always use lsof -n -P.
  • Distinction Between +d and +D: The lowercase +d /path flag searches only the top-level directory without descending into subfolders, running significantly faster than the recursive +D flag across sprawling filesystem hierarchies.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.