lsof - Listing Open Files and Ports
What You'll Learn
- How to find which process holds a file or port with
lsof - How to diagnose "
device is busyon unmount" and "port already in use" - Why disk space is not freed after delete (deleted-but-open files)
Quick Summary
- Port check →
lsof -i :8080 - Files a process opened →
lsof -p <PID> - Who holds this file →
lsof /path/to/file - If output is empty or slow, add
sudoand-n -P
Prerequisites
- OS: Ubuntu / RHEL-based (
lsofmay be a separate package) - If missing:
sudo apt install lsof/sudo dnf install lsof - You need
sudoto see other users' processes
What Is lsof?
Conclusion: lsof (list open files) lists every currently open file. In Linux, sockets and pipes are files too, so lsof doubles as a network investigation tool.
In Linux, almost everything is a file. That includes not just regular files and directories, but network sockets, pipes, devices, and block devices. Because lsof lists all of them in one place, it becomes a Swiss-army knife for troubleshooting.
Run with no arguments and it dumps every open file system-wide.
$ sudo lsof | head
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root cwd DIR 254,1 4096 2 / systemd 1 root txt REG 254,1 1620224 393431 /usr/lib/systemd/systemd sshd 812 root 3u IPv4 18654 0t0 TCP *:ssh (LISTEN)
Here is what the columns mean:
COMMAND/PID/USER: the process holding the file and its ownerFD: file descriptor (cwd=current directory,txt=executable,3u=fd 3 open for read+write, etc.)TYPE:REG(regular file) /DIR/IPv4/unix(UNIX socket), etc.NAME: file path or connection endpoint
The unfiltered dump is rarely useful. The filtering in the sections below is the real workflow.
Which Process Is Using a Port?
Conclusion:
lsof -i :PORTidentifies the process holding a port, with its PID. It is the go-to for hunting down "Address already in use".
The most common use is finding who occupies a port. -i filters to network connections.
# Process using port 8080 $ sudo lsof -i :8080
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME node 24531 hide 22u IPv4 184213 0t0 TCP *:8080 (LISTEN)
Once you have the PID (24531 here), you can stop it directly.
$ kill 24531
To list only listening ports, filter by protocol and state.
# Show all TCP ports in LISTEN state $ sudo lsof -iTCP -sTCP:LISTEN -P -n
-P: do not convert port numbers to names likehttp(keep them numeric)-n: do not resolve IP addresses via DNS
-P -n skips name resolution, making the output faster and easier to read. Make it part of your default investigation flags.
You can also target a specific host or port.
$ sudo lsof -i TCP:22 # connections related to port 22 (SSH) $ sudo lsof -i @192.168.1.10 # connections with a specific host
How to See Files a Process Has Open?
Conclusion:
lsof -p <PID>lists every file the process has open (logs, sockets, libraries). It is useful for inspecting a process whose behavior is unclear.
# Files opened by PID 24531 $ sudo lsof -p 24531
You see at a glance where it writes logs, which config files it reads, and which sockets it has open. Specify multiple PIDs with commas.
$ sudo lsof -p 24531,800
You can also filter by user or command name.
$ sudo lsof -u hide # files opened by user hide $ sudo lsof -c nginx # processes whose command starts with nginx
Combining -u, -c, and -i is an OR match (any of them). To require all conditions (AND), add -a.
# nginx AND a TCP connection $ sudo lsof -a -c nginx -i TCP
Who Is Holding This File?
Conclusion:
lsof /pathreverse-looks-up the processes that have a file (or directory) open. It is the fix for "device is busy" on unmount.
Everyone has hit target is busy when trying to unmount a USB drive. The cause is simple: something has a file under that directory open.
# Find the process holding /mnt/usb $ sudo lsof /mnt/usb
To search a directory tree recursively, use +D.
$ sudo lsof +D /mnt/usb
Once you know the PID, terminate the process or have it change out of the directory, and the unmount will succeed.
Combine with kill
-t outputs only the PIDs, ready to pipe straight to kill.
# Kill every process holding /mnt/usb $ sudo kill $(sudo lsof -t /mnt/usb)
Force-killing is a last resort. Check what the processes are (without -t) first.
Deleted a File but Disk Is Still Full
Conclusion: Deleting a file that a process still has open does not free the space until the process exits. Use
lsof | grep deletedto find the holder.
"I rm'd a huge log but df shows no extra free space" is a classic trap. While any process has the file open, rm only removes the link; the actual data (inode) stays until the descriptor is closed.
# Find files that are deleted but still held open $ sudo lsof -nP | grep '(deleted)'
java 3120 app 5w REG 254,1 2147483648 394102 /var/log/app/huge.log (deleted)
To reclaim the space here, you must restart the process (or close the offending fd). rm huge.log alone is clearly not enough.
For service log files, prefer rotation (logrotate with copytruncate) or truncate -s 0 over rm. A plain rm easily creates this deleted-but-open state.
Common Options Cheat Sheet
Conclusion: Start from one of three entry points —
-i(port),-p(process), or a path (file). Then speed it up with-n -Pand pipe to kill with-t.
| Goal | Command |
|---|---|
| Check who holds a port | lsof -i :8080 |
| List listening ports | lsof -iTCP -sTCP:LISTEN -P -n |
| Files opened by a process | lsof -p <PID> |
| Files opened by a user | lsof -u <user> |
| Process holding a file | lsof /path/to/file |
| Recurse a directory tree | lsof +D /path |
| Deleted-but-open files | lsof -nP | grep '(deleted)' |
| PID-only output (pipe to kill) | lsof -t /path |
Copy-paste investigation templates
# Find the process occupying a port sudo lsof -i :8080 -P -n # Find the cause of "device is busy" sudo lsof +D /mnt/usb # Find deleted files still eating disk space sudo lsof -nP | grep '(deleted)'