lsof: какие процессы слушают порт и держат файл
Сервис не стартует — порт 8080 занят. Разбираешься, кто именно его держит, и попутно выясняется, что тот же процесс держит конфиг, который ты хотел отредактировать. lsof отвечает на оба вопроса: какие процессы открыли файлы и сокеты.
Слушающие порты
Классическая задача — найти, кто слушает конкретный порт.
| Флаг | Действие |
|---|---|
-i | Показать интернет-сокеты |
-n | Без DNS-резолва (IP вместо hostname) |
-P | Без преобразования портов (80 вместо http) |
Без -n -P lsof тратит время на DNS и резолвит порты в имена сервисов из /etc/services. На продакшене это лишние секунды.
Если нужен конкретный порт:
Чтобы узнать, какой процесс слушает порт 443, достаточно lsof -i :443 -n -P. Вывод покажет PID, пользователя и тип сокета (IPv4/IPv6, TCP/UDP).
Для фильтра по протоколу:
Процессы в директории
Нужно понять, какие процессы работают с файлами внутри директории? lsof +D рекурсивно обходит директорию и показывает все открытые файлы.
На директории с тысячами файлов (например, /tmp) команда работает долго. Она обходит файловую систему, а не опрашивает ядро — это O(n) операция.
Для нерекурсивного поиска (только файлы непосредственно в директории, без поддиректорий) используй find + xargs:
Результат покажет все процессы, которые держат открытыми файлы из указанной директории. Типичный сценарий — нельзя отмонтировать раздел, потому что кто-то работает с файлами внутри.
Инвентарь одного процесса
Когда PID известен, полный список открытых файлов:
Вывод включает регулярные файлы, библиотеки (.so), сокеты и pipe. Для быстрого grep по типу:
REG — Regular file, DIR — directory, FIFO — named pipe, IPv4/IPv6 — сетевые сокеты. TYPE в выводе lsof совпадает с типом в /proc/PID/fd.
Обратная операция — найти PID по файлу:
Если файл занят (ротация логов не проходит, unmount не работает), эта команда покажет виновника.
Краткий вывод команды
По умолчанию lsof обрезает имя команды до 9 символов. Для длинных имен (java, python) этого может не хватать:
+c 0 означает «без ограничения». Удобно при работе с Java-процессами, где в командной строке десятки символов classpath.
Быстрый справочник
| Команда | Назначение |
|---|---|
lsof -i :PORT | Кто слушает PORT |
lsof -i TCP | Все TCP-соединения |
lsof -i UDP | Все UDP-соединения |
lsof -p PID | Файлы процесса PID |
lsof +D DIR | Процессы в директории |
lsof /path/to/file | PID, открывший файл |
lsof +c N | Ограничить имя команды N символами |
lsof -u USER | Все открытые файлы пользователя |
lsof -c CMD | Файлы процессов с именем CMD |
Типичные ошибки
lsof не установлен — на минимальных образах приходится доустанавливать:
Нет прав на чтение /proc — для просмотра чужих процессов нужен root или membership в группе, которая имеет доступ. Обычно это означает запуск через sudo.
lsof зависает — ядро не отвечает на запросы файловых дескрипторов (проблемы с NFS, подвисший filesystem). Ctrl+C и перезапуск с таймаутом.
lsof — один из тех инструментов, к которым возвращаешься каждый раз, когда разбираешься с заблокированными ресурсами. Три команды покрывают 90% задач: -i :PORT для порта, +D /path для директории, -p PID для процесса.