lsof (list open files) shows which processes have which files open. Since Unix treats everything as a file — including network connections, devices, and pipes — lsof is incredibly powerful for system debugging.

Basic Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# List all open files (overwhelming)
lsof

# List open files for specific file
lsof /var/log/syslog

# List open files for user
lsof -u username

# List open files for process
lsof -p 1234

Find What’s Using a File

1
2
3
4
5
6
7
8
# Who has this file open?
lsof /path/to/file

# Who has files open in this directory?
lsof +D /var/log

# Recursive directory search
lsof +D /var/log/

“Device or resource busy” Debugging

1
2
3
4
5
# Can't unmount? Find what's using it
lsof +D /mnt/usb

# Find open files on filesystem
lsof /dev/sda1

Find What’s Using a Port

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# What's on port 8080?
lsof -i :8080

# What's on port 80 or 443?
lsof -i :80 -i :443

# All network connections
lsof -i

# TCP only
lsof -i TCP

# UDP only
lsof -i UDP

Specific Protocol and Port

1
2
3
4
5
6
7
8
# TCP port 22
lsof -i TCP:22

# UDP port 53
lsof -i UDP:53

# Port range
lsof -i :1-1024

Filter by Process

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# By PID
lsof -p 1234

# By process name
lsof -c nginx

# By multiple process names
lsof -c nginx -c apache

# Exclude process
lsof -c ^nginx

Filter by User

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# By username
lsof -u www-data

# By UID
lsof -u 1000

# Multiple users
lsof -u user1,user2

# Exclude user
lsof -u ^root

Network Connections

List All Connections

1
2
3
4
5
6
7
8
# All internet connections
lsof -i

# Established connections only
lsof -i | grep ESTABLISHED

# Listening sockets
lsof -i | grep LISTEN

Connections to Specific Host

1
2
3
4
5
6
7
8
# Connections to specific IP
lsof -i @192.168.1.100

# Connections to hostname
lsof -i @example.com

# Connections to specific host and port
lsof -i @192.168.1.100:22

IPv4 vs IPv6

1
2
3
4
5
# IPv4 only
lsof -i 4

# IPv6 only
lsof -i 6

Output Formatting

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Terse output (parseable)
lsof -t /path/to/file
# Returns just PIDs

# No header
lsof +D /var/log | tail -n +2

# Specific fields
lsof -F p /path/to/file  # PID only
lsof -F c /path/to/file  # Command only

Combining Filters

By default, filters are OR’d. Use -a to AND them:

1
2
3
4
5
# Files by nginx AND network connections (AND)
lsof -a -c nginx -i

# Files by user1 OR user2 (OR, default)
lsof -u user1 -u user2

Practical Examples

Find and Kill Process Using Port

1
2
3
4
5
6
7
8
9
# Find PID using port 3000
lsof -t -i :3000
# Returns: 12345

# Kill it
kill $(lsof -t -i :3000)

# Force kill
kill -9 $(lsof -t -i :3000)

Debug “Address Already in Use”

1
2
3
4
5
6
# What's already using port 8080?
lsof -i :8080

# Sample output:
# COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
# node    1234   user   21u  IPv4  12345      0t0  TCP *:http-alt (LISTEN)

Find Deleted Files Still Open

1
2
3
4
5
# Files marked deleted but still open (disk space won't free)
lsof | grep deleted

# Or more specifically
lsof +L1

This is common when log files are deleted but the process still has them open.

Check What’s Writing to a File

1
2
3
4
5
# Who's writing to this log?
lsof /var/log/app.log

# Follow file descriptor
lsof -p $(pgrep app) | grep log

Debug NFS Issues

1
2
3
4
5
# Find processes using NFS mount
lsof +D /nfs/share

# Find stale NFS handles
lsof | grep -i nfs

Monitor Network Activity

1
2
3
4
5
# Watch connections in real-time
watch 'lsof -i -n | head -20'

# Count connections per process
lsof -i | awk '{print $1}' | sort | uniq -c | sort -rn

Find Open Files by Process Name

1
2
3
4
5
6
7
8
# All files nginx has open
lsof -c nginx

# Count open files
lsof -c nginx | wc -l

# Just regular files
lsof -c nginx | grep REG

Debug “Too Many Open Files”

1
2
3
4
5
6
7
8
# Count open files per process
lsof -u username | awk '{print $2}' | sort | uniq -c | sort -rn | head

# Check process limit
cat /proc/1234/limits | grep "open files"

# Count for specific PID
lsof -p 1234 | wc -l

Understanding Output

CnnnnOggggMiiiiMnnnnAxxxxND1111P2222I3333D4444UrrrrSooooEooooRttttcrtFwtx6DddtuTIYDDRPPIIEvERRG4DE2221V5552I3333C,,,4E1115SI1Z2E3/444O0050F996tF667012N3O4TD5CE226PN///*Au:Ms8Er0/s(bLiInS/TnEgNi)nx

FD (File Descriptor):

  • cwd = current working directory
  • rtd = root directory
  • txt = program text (executable)
  • mem = memory-mapped file
  • 0u, 1u, 2u = stdin, stdout, stderr
  • Numbers = file descriptors (u=read/write, r=read, w=write)

TYPE:

  • REG = regular file
  • DIR = directory
  • CHR = character device
  • BLK = block device
  • FIFO = named pipe
  • UNIX = Unix domain socket
  • IPv4/IPv6 = network connection

Performance Note

lsof can be slow on systems with many open files. Use filters to narrow scope:

1
2
3
4
5
6
7
8
# Slow (scans everything)
lsof | grep pattern

# Fast (only checks specific file)
lsof /specific/file

# Fast (only checks network)
lsof -i :8080

Quick Reference

TaskCommand
Who’s using filelsof /path/to/file
Who’s using portlsof -i :port
Process’s open fileslsof -p PID
User’s open fileslsof -u username
Just PIDslsof -t ...
Network onlylsof -i
TCP listenerslsof -i TCP | grep LISTEN
Deleted but openlsof +L1

lsof answers “what’s using this?” — whether “this” is a file, port, or filesystem. Combine it with kill, and you can quickly resolve “resource busy” and “address in use” errors. It’s one of those tools that seems unnecessary until you need it, then becomes indispensable.