In Unix and Linux operating systems, the foundational architectural philosophy is that “everything is a file.” Regular plain-text documents, hardware block devices, mounted filesystems, Unix domain sockets, pipes, and active TCP/UDP network connections are all represented as file descriptors inside the Linux kernel. When an administrator attempts to unmount a storage drive and receives a frustrating device is busy error, or attempts to launch Nginx only to be told that port 80 is already in use, determining which specific process is holding the resource open is critical. The definitive command-line utility for inspecting active file descriptors and network connections in Linux is lsof (List Open Files).
Why lsof is Essential for Linux Administration
The lsof utility communicates directly with the kernel’s virtual /proc filesystem to deliver profound diagnostic transparency:
- Universal Resource Inspection: Because Linux treats network sockets, devices, and directories as files,
lsofprovides unified inspection across physical disk files, active network ports, and inter-process communication pipes. - Process Attribution: Maps open files directly to the executing Process ID (PID), command name, and user account that owns the process.
- Resolving Busy Filesystem Unmounts: Pinpoints the exact background process or user shell preventing an external drive or NFS volume from unmounting cleanly.
- Security Auditing: Instantly exposes hidden network backdoors, rogue listening ports, and unauthorized background processes established by malicious actors.
Step-by-Step: Installing lsof on Linux Distributions
While lsof is standard on many full desktop installations, minimal cloud VPS templates and Docker containers often omit it:
On Ubuntu, Debian, and Linux Mint:
sudo apt update
sudo apt install lsof -y
On Fedora, RHEL, CentOS, Rocky Linux, and AlmaLinux:
sudo dnf install lsof -y
On Arch Linux and Manjaro:
sudo pacman -S lsof
Understanding Standard lsof Output Columns
Running the bare command without filters lists every open file across the entire operating system:
sudo lsof
The output is structured across informative diagnostic columns:
- COMMAND: The name of the binary executable (e.g.,
nginx,sshd,python3). - PID: The unique Process ID assigned by the kernel.
- USER: The Linux user account running the process (e.g.,
root,www-data). - FD (File Descriptor): The descriptor number and access mode (
rfor read,wfor write,ufor read/write,cwdfor current working directory). - TYPE: The file type (
REGfor regular file,DIRfor directory,IPv4/IPv6for network socket,FIFOfor pipe). - DEVICE: Disk device numbers.
- SIZE/OFF: File size in bytes or current offset pointer.
- NODE: Filesystem inode number or protocol state.
- NAME: Full filesystem path, socket address, or listening port.
Finding Processes Holding Network Ports (-i Flag)
The -i argument inspects internet network sockets, making lsof an indispensable alternative to netstat and ss:
1. Listing All Active Network Connections
sudo lsof -i
2. Finding Which Process is Listening on a Specific Port
If Apache or Nginx fails to start because port 80 or 443 is blocked:
sudo lsof -i :80
sudo lsof -i :443
The output immediately identifies the offending PID, allowing you to stop or terminate the conflicting daemon.
3. Filtering by Protocol (TCP vs UDP) and State
To list all processes actively listening on TCP ports:
sudo lsof -i TCP -s TCP:LISTEN
4. Finding Outbound Connections to a Specific IP or Host
sudo lsof -i @192.168.1.50
Finding Which Process is Locking a File or Directory
When you cannot delete a file or unmount a USB drive due to active process locks:
1. Finding Processes Using a Specific File
sudo lsof /var/log/syslog
2. Finding Processes Inside a Mounted Directory (+D Flag)
To find every process actively holding a directory or USB mount point open:
sudo lsof +D /mnt/backup_drive
Once you identify the PIDs holding the mount point, you can terminate them cleanly via kill <PID> and execute umount /mnt/backup_drive without errors.
Filtering by User and Process Name
Isolate activity generated by specific system accounts or services:
1. Listing Files Opened by a Specific User (-u Flag)
sudo lsof -u www-data
2. Filtering by Process Command Name (-c Flag)
To view all files and network sockets opened by the MySQL daemon:
sudo lsof -c mysqld
3. Filtering by Exact Process ID (-p Flag)
sudo lsof -p 1420
lsof vs fuser vs ss Network Tools Comparison
| Feature | lsof | fuser | ss (Socket Statistics) |
|---|---|---|---|
| Primary Focus | Comprehensive files, devices, & sockets | Process identification on files/mounts | Network sockets & TCP metrics only |
| Kill Offending Process | Requires manual kill <PID> |
Native -k flag terminates process |
No |
| Port Number Lookup | Intuitive (lsof -i :80) |
Supported (fuser 80/tcp) |
Supported (ss -tulpn) |
| Detail Level | Extremely high (FD, inode, full paths) | Concise (outputs PIDs only) | High (network protocol metrics) |
| Speed on Large Systems | Can be slow if scanning entire /proc | Fast | Blazing fast (Kernel Netlink) |
Troubleshooting Common lsof Issues
To maximize performance when diagnosing Linux servers:
- DNS Resolution Delays (-n Flag): By default,
lsofattempts to resolve IP addresses into hostnames via reverse DNS, causing severe lag if DNS servers are slow. Always include-nto output raw IP numbers immediately:sudo lsof -i -n. - Port Name Resolution Delays (-P Flag): Similarly,
lsofconverts port numbers to protocol names (e.g., converting 80 to http). Pass-Pto force numeric ports:sudo lsof -i -n -P. - Executing Without Sudo: Running
lsofas an unprivileged user only displays files opened by your own user processes, concealing system services and daemons. Always run withsudofor complete administrative visibility.
Frequently Asked Questions
Can lsof help recover deleted files that are still held open by a process?
Yes. If a file was deleted via rm while a process (like a database or log reader) still has it open, lsof displays the file with a (deleted) tag. You can recover the file contents by copying its file descriptor directly from /proc/<PID>/fd/<FD_NUM>.
What does lsof -t do?
The -t (terse) flag outputs only the raw Process IDs (PIDs) without headers. This is ideal for command piping, such as automatically killing all processes holding a port: sudo kill -9 $(sudo lsof -t -i :8080).
Can I combine multiple filters with AND logic?
By default, multiple flags in lsof execute with OR logic. To force AND logic (e.g., matching a specific user AND a specific port), include the -a flag: sudo lsof -a -u www-data -i :443.