Перейти к содержимому

lsof: какие процессы слушают порт и держат файл

Сервис не стартует — порт 8080 занят. Разбираешься, кто именно его держит, и попутно выясняется, что тот же процесс держит конфиг, который ты хотел отредактировать. lsof отвечает на оба вопроса: какие процессы открыли файлы и сокеты.

Слушающие порты

Классическая задача — найти, кто слушает конкретный порт.

lsof -i -n -P
ФлагДействие
-iПоказать интернет-сокеты
-nБез DNS-резолва (IP вместо hostname)
-PБез преобразования портов (80 вместо http)

Без -n -P lsof тратит время на DNS и резолвит порты в имена сервисов из /etc/services. На продакшене это лишние секунды.

Если нужен конкретный порт:

lsof -i :8080 -n -P
Подсказка

Чтобы узнать, какой процесс слушает порт 443, достаточно lsof -i :443 -n -P. Вывод покажет PID, пользователя и тип сокета (IPv4/IPv6, TCP/UDP).

Для фильтра по протоколу:

lsof -i TCP:22 -n -P    # только TCP
lsof -i UDP:53 -n -P    # только UDP

Процессы в директории

Нужно понять, какие процессы работают с файлами внутри директории? lsof +D рекурсивно обходит директорию и показывает все открытые файлы.

lsof +D /var/log/
Предупреждение

На директории с тысячами файлов (например, /tmp) команда работает долго. Она обходит файловую систему, а не опрашивает ядро — это O(n) операция.

Для нерекурсивного поиска (только файлы непосредственно в директории, без поддиректорий) используй find + xargs:

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

Результат покажет все процессы, которые держат открытыми файлы из указанной директории. Типичный сценарий — нельзя отмонтировать раздел, потому что кто-то работает с файлами внутри.

Инвентарь одного процесса

Когда PID известен, полный список открытых файлов:

lsof -p 1234

Вывод включает регулярные файлы, библиотеки (.so), сокеты и pipe. Для быстрого grep по типу:

lsof -p 1234 | grep REG      # только файлы
lsof -p 1234 | grep FIFO     # pipe
lsof -p 1234 | grep IPv      # сетевые сокеты
Примечание

REG — Regular file, DIR — directory, FIFO — named pipe, IPv4/IPv6 — сетевые сокеты. TYPE в выводе lsof совпадает с типом в /proc/PID/fd.

Обратная операция — найти PID по файлу:

lsof /var/log/syslog

Если файл занят (ротация логов не проходит, unmount не работает), эта команда покажет виновника.

Краткий вывод команды

По умолчанию lsof обрезает имя команды до 9 символов. Для длинных имен (java, python) этого может не хватать:

lsof +c 0 -i -n -P    # показать полное имя команды
lsof +c 20 -p 1234    # до 20 символов
lsof +c 0 -p $(pgrep -f nginx)
Подсказка

+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/filePID, открывший файл
lsof +c NОграничить имя команды N символами
lsof -u USERВсе открытые файлы пользователя
lsof -c CMDФайлы процессов с именем CMD

Типичные ошибки

lsof не установлен — на минимальных образах приходится доустанавливать:

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

Нет прав на чтение /proc — для просмотра чужих процессов нужен root или membership в группе, которая имеет доступ. Обычно это означает запуск через sudo.

lsof зависает — ядро не отвечает на запросы файловых дескрипторов (проблемы с NFS, подвисший filesystem). Ctrl+C и перезапуск с таймаутом.


lsof — один из тех инструментов, к которым возвращаешься каждый раз, когда разбираешься с заблокированными ресурсами. Три команды покрывают 90% задач: -i :PORT для порта, +D /path для директории, -p PID для процесса.