List Open Files — and sockets, devices, everything
lsof shows files open by which processes. On Unix everything is a file (network sockets, ttys, pipes), so lsof answers questions like "what's holding port 8080?" and "who has this disk open so I can't unmount?"
Daily recipes
lsof -i :8080— what listens on / is connected to port 8080.lsof -i TCP:LISTEN— every TCP listener.lsof -nP -iTCP -sTCP:LISTEN— listeners with numeric IPs and ports (faster, no DNS).lsof /Volumes/Backup— what's keeping that volume busy.lsof -p PID— every fd held by a process.lsof -u $USER— files held by your user.lsof | grep deleted— files unlinked but still open (common cause of "disk full but I deleted everything").
The classic incidents lsof solves
- Port already in use.
lsof -i :3000, see the PID, kill the stale dev server. - Can't unmount.
lsof /Volumes/Disk, see who's open, close them. - df shows full but du doesn't.
lsof | grep deletedfinds processes holding deleted files; restart the process to release.
The faster modern alternative
ss on Linux replaces a lot of lsof -i. On macOS, lsof is still the answer. Either way, alias the verbose form: alias ports='lsof -nP -iTCP -sTCP:LISTEN' and ports becomes a one-word answer to "what's listening?"
Distinguish open from active use
Holding a file descriptor does not mean a process is reading or writing now, and a short-lived open can disappear between snapshots. Align observation time and sample repeatedly or use filesystem and network tracing.
A deleted file can still consume space
Unix keeps data blocks until the last open descriptor closes, even after unlink. That can make du shrink while df does not. Prefer log reopen or a normal restart path over killing the process blindly.