lsof: find open files, ports, and processes
lsof means list open files. On Unix-like systems, “files” include regular files, directories, devices, pipes, and network sockets. That makes lsof useful for answering questions like:
- Which process is using this file?
- What is listening on this port?
- Which files does this process have open?
Run it without arguments and it lists every open file it is allowed to see:
This is normally too much information, so in practice you give lsof a selector or filter its output.
Quickly scanning the output
A row might look like this:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
python 43127 alex 5u IPv4 ... 0t0 TCP *:8000 (LISTEN)
Read it from left to right:
| Column |
Meaning |
COMMAND |
Program name |
PID |
Process ID |
USER |
Process owner |
FD |
File descriptor; cwd is the current directory and a number is an open descriptor |
TYPE |
Kind of file, such as REG, DIR, IPv4, or IPv6 |
NAME |
File path, device, or network address |
For a quick visual search, pipe the output into rg (ripgrep):
lsof -nP | rg -i 'python|node'
lsof -nP -i | rg 'LISTEN'
Here, -n keeps host addresses numeric and -P keeps port numbers numeric. Both make network output faster and easier to scan.
Finding what you need
| Task |
Command |
| Find processes using a file |
lsof /path/to/file |
| Search a directory |
lsof +d /path/to/directory |
| Search a directory recursively |
lsof +D /path/to/directory |
| Show files opened by a PID |
lsof -p 43127 |
| Show files opened by a command |
lsof -c python |
| Show files opened by a user |
lsof -u alex |
| Show network files with numeric addresses |
lsof -nP -i |
| Find anything using TCP port 8000 |
lsof -nP -iTCP:8000 |
| Find the listener on TCP port 8000 |
lsof -nP -iTCP:8000 -sTCP:LISTEN |
| Find network files opened by one PID |
lsof -nP -a -p 43127 -i |
| Search the human-readable output |
lsof -nP | rg -i 'python|node' |
| Return only matching PIDs |
lsof -t -iTCP:8000 -sTCP:LISTEN |
lsof normally combines selection options with OR. Use -a when every condition must match, as in the PID-and-network example above.
Some processes owned by other users may not appear. If a result seems to be missing, retry the same query with sudo.
Parsing the result
The default columns are designed for people, so avoid splitting them with cut or awk in a script. Ask lsof for the exact data you need instead.
Use -t when a command needs only process IDs:
lsof -t -iTCP:8000 -sTCP:LISTEN
Use -F for structured, machine-readable fields. Each value starts with a field letter; for example, p is a PID, c is a command, and n is a file name:
lsof -F pcn -iTCP:8000 -sTCP:LISTEN
The basic workflow is: narrow the results with lsof selectors, use rg for a quick visual scan, and use -t or -F when another command needs to consume the result.