# lsof: which processes listen on port and hold file

LLMS index: [llms.txt](/en/llms.txt)

---

Service won't start — port 8080 is already bound. You dig into who's holding it, and discover the same process has your config file open while you're trying to edit it. lsof answers both questions: which processes opened which files and sockets.

## Listening Ports

The classic task — find who is listening on a specific port.

```bash
lsof -i -n -P
```

| Flag | Effect |
|------|--------|
| `-i` | Show internet sockets |
| `-n` | Skip DNS resolution (show IP instead of hostname) |
| `-P` | Skip port-to-service conversion (show 80 instead of http) |

Without `-n -P`, lsof wastes time on DNS lookups and resolves ports through /etc/services. On production hosts that's unnecessary seconds.

For a specific port:

```bash
lsof -i :8080 -n -P
```

> [!TIP]
> To find what process is listening on port 443, `lsof -i :443 -n -P` is sufficient. Output shows PID, user, and socket type (IPv4/IPv6, TCP/UDP).

To filter by protocol:

```bash
lsof -i TCP:22 -n -P    # TCP only
lsof -i UDP:53 -n -P    # UDP only
```

## Processes in a Directory

Need to see which processes are working with files inside a directory? `lsof +D` recursively walks the directory and lists all open files.

```bash
lsof +D /var/log/
```

> [!WARNING]
> On directories with thousands of files (for example, /tmp), this command runs slowly. It traverses the filesystem rather than querying the kernel — this is an O(n) operation.

For non-recursive search (files directly in the directory, no subdirectories), use find + xargs:

```bash
find /etc/nginx -maxdepth 1 -type f -exec lsof {}
```

The result shows all processes holding open files from the specified directory. Typical scenario — cannot unmount a partition because someone is working with files inside it.

## Single Process Inventory

When the PID is known, list all open files:

```bash
lsof -p 1234
```

Output includes regular files, libraries (.so), sockets, and pipes. To grep by type:

```bash
lsof -p 1234 | grep REG      # regular files only
lsof -p 1234 | grep FIFO     # pipes
lsof -p 1234 | grep IPv      # network sockets
```

> [!NOTE]
> REG — Regular file, DIR — directory, FIFO — named pipe, IPv4/IPv6 — network sockets. The TYPE in lsof output matches the type in /proc/PID/fd.

The reverse operation — find PID by file:

```bash
lsof /var/log/syslog
```

If the file is locked (log rotation fails, unmount does not work), this command shows the culprit.

## Truncated Command Names

By default, lsof truncates command names to 9 characters. For long names (java, python) this may not be enough:

```bash
lsof +c 0 -i -n -P    # show full command name
lsof +c 20 -p 1234    # up to 20 characters
```

```bash
lsof +c 0 -p $(pgrep -f nginx)
```

> [!TIP]
> `+c 0` means "no limit". Useful when working with Java processes where the command line contains dozens of characters of classpath.

## Quick Reference

| Command | Purpose |
|---------|---------|
| `lsof -i :PORT` | Who listens on PORT |
| `lsof -i TCP` | All TCP connections |
| `lsof -i UDP` | All UDP connections |
| `lsof -p PID` | Files opened by PID |
| `lsof +D DIR` | Processes in directory |
| `lsof /path/to/file` | PID that opened file |
| `lsof +c N` | Limit command name to N characters |
| `lsof -u USER` | All open files for user |
| `lsof -c CMD` | Files for processes named CMD |

## Common Issues

**lsof not installed** — minimal images require installation:

```bash
apt install lsof    # Debian/Ubuntu
yum install lsof    # RHEL/CentOS
```

**No read access to /proc** — viewing other users' processes requires root or group membership with access. Usually means running through sudo.

**lsof hangs** — kernel not responding to file descriptor requests (NFS issues, stalled filesystem). Ctrl+C and restart with a timeout.

---

lsof is one of those tools you return to every time you troubleshoot locked resources. Three commands cover 90% of the tasks: `-i :PORT` for ports, `+D /path` for directories, `-p PID` for processes.
