Зачем
Когда нужно ответить на вопросы:
- «Какой процесс держит этот порт?»
- «Кто захватил этот файл и не отпускает?»
- «Почему диск full если
duпоказывает мало?»
lsof - главный ответчик. Без sudo показывает только твои процессы;
с sudo - все.
Самые ходовые формы
lsof -p 1234 # все fd конкретного [[process-and-pid]]
lsof -i # все сетевые сокеты
lsof -i :8080 # кто слушает или связан с портом 8080
lsof -i tcp # только TCP
lsof -nP -i # без resolv: -n не резолвить хосты, -P не резолвить порты
lsof /var/log/app.log # кто открыл этот конкретный файл
lsof +D /var/lib/docker # все открытые внутри директории (-D = recurse)
Самый полезный one-liner: lsof | grep deleted
Когда df -h показывает full, а du -sh / - нет:
sudo lsof | grep deleted
Это процессы которые держат открытым файл, удалённый из ФС. Inode жив пока fd не закроется. Самый частый виновник - приложение с ротацией логов которое забыло переоткрыть лог-файл.
Колонки в выводе
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 900 www 6u IPv4 12345 0t0 TCP *:80 (LISTEN)
- FD: число + тип.
6u- fd 6, открыт на read+write.cwd,rtd,txt,mem- спецтипы (cwd = текущая директория, txt = бинарь, mem = mmap) - TYPE:
REG(файл),DIR,CHR(char device),IPv4/IPv6,unix,FIFO - NAME: путь либо
host:port → host:portдля сокетов
Альтернатива через /proc
Без lsof то же видно через /proc/<pid>/fd/*:
ls -l /proc/900/fd/ # каждый fd - symlink на цель
lsof это просто удобный агрегатор того же.