lsof - Listing Open Files and Ports

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 busy on unmount" and "port already in use"
  • Why disk space is not freed after delete (deleted-but-open files)

Quick Summary

  • Port checklsof -i :8080
  • Files a process openedlsof -p <PID>
  • Who holds this filelsof /path/to/file
  • If output is empty or slow, add sudo and -n -P

Prerequisites

  • OS: Ubuntu / RHEL-based (lsof may be a separate package)
  • If missing: sudo apt install lsof / sudo dnf install lsof
  • You need sudo to 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 owner
  • FD: 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 :PORT identifies 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 like http (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 /path reverse-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 deleted to 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 -P and 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)'

Next Reading