Linux

lsof: Полное руководство по команде для поиска открытых файлов

Команда lsof (list open files) — незаменимый инструмент системного администратора и разработчика для диагностики проблем с файлами, портами и процессами. Это руководство покажет, как эффективно использовать lsof для решения реальных задач.

Обновлено 16 февраля 2026 г.
15-20 мин
Средняя
FixPedia Team
Применимо к:Ubuntu 20.04+CentOS 7+Debian 10+RHEL 8+Любой дистрибутив с установленным пакетом lsof

Введение / Зачем это нужно

lsof (List Open Files) — это мощная утилита командной строки в Linux, которая позволяет увидеть, какие процессы в системе имеют открытыми файлы, каталоги, сетевые сокеты, устройства и т.д. В Unix-подобных системах почти всё является файлом, поэтому эта команда — основной инструмент диагностики для системных администраторов, разработчиков и DevOps-инженеров.

Вы научитесь решать частые проблемы:

  • «Порт 8080 уже занят, но каким процессом?»
  • «Не могу удалить файл /tmp/app.log, говорится, что он используется. Кто его держит?»
  • «Какие сетевые соединения активны у моего приложения?»
  • «Почему процесс потребляет так много дескрипторов?»

Это руководство содержит конкретные, проверенные команды с объяснениями, которые вы сможете использовать сразу.

Требования / Подготовка

  1. Доступ к терминалу Linux (Ubuntu, CentOS, Debian, RHEL, Fedora и др.).
  2. Права суперпользователя (sudo). Многие команды, особенно связанные с сетевыми портами и процессами других пользователей, требуют прав администратора для корректного отображения информации.
  3. Установленный пакет lsof. В большинстве дистрибутивов он есть по умолчанию, но в минимальных установках может отсутствовать.
    • Debian/Ubuntu: sudo apt update && sudo apt install lsof
    • RHEL/CentOS/Fedora: sudo yum install lsof или sudo dnf install lsof
  4. Базовое понимание командной строки и концепции PID (идентификатор процесса).

Пошаговая инструкция

Шаг 1: Базовый синтаксис и просмотр всех открытых файлов

Запуск lsof без аргументов выведет список всех открытых файлов текущего пользователя.

lsof

Пример вывода (упрощённо):

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    1234 user  cwd    DIR    8,1     4096    2 /
bash    1234 user  txt    REG    8,1  1028096 12345 /bin/bash
bash    1234 user  mem    REG    8,1  1985224 67890 /lib/x86_64-linux-gnu/libc-2.31.so
...

Ключевые столбцы:

  • COMMAND — имя исполняемого файла процесса.
  • PID — идентификатор процесса.
  • USER — владелец процесса.
  • FD — файловый дескриптор (cwd — текущий каталог, txt — исполняемый код, mem — отображённая в память область).
  • TYPE — тип файла (REG — обычный файл, DIR — каталог, CHR — символьное устройство, IPv4/IPv6 — сетевой сокет).
  • NAME — путь к файлу или информация о сокете.

Для полной системной картины (всех пользователей) используйте sudo:

sudo lsof

Шаг 2: Поиск процессов, открывших конкретный файл или каталог

Это самая частая задача: «Кто использует этот файл?».

Для одного файла:

lsof /path/to/file.log

Пример: lsof /var/log/syslog

Рекурсивный поиск по каталогу (все файлы внутри):

lsof +D /home/user/documents/

⚠️ Важно: Опция +D может работать очень медленно на больших каталогах, так как проверяет каждый подкаталог. Для быстрой проверки конкретного файла используйте первый вариант.

Шаг 3: Поиск процесса по его PID (что открыл процесс)

Если вы знаете PID процесса (например, 5678), посмотрите, какие ресурсы он использует:

lsof -p 5678

Можно указать несколько PID через запятую: lsof -p 5678,9012.

Это полезно для анализа работы запущенного демона, контейнера или подозрительного процесса.

Шаг 4: Поиск процесса, слушающего сетевой порт

Классическая задача: «Порт 3000 занят, какой процесс его слушает?».

sudo lsof -i :3000

Пример вывода:

COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
node    4321 user   20u  IPv6 123456      0t0  TCP *:3000 (LISTEN)

Здесь видно, что порт 3000 слушает процесс node (Node.js) с PID 4321.

Поиск по имени службы/порта (если порт известен, например, 80 для HTTP):

sudo lsof -i :http
# или
sudo lsof -i :80

Шаг 5: Расширенная фильтрация сетевых соединений

Комбинация опций -i позволяет тонко настраивать фильтрацию.

Только TCP-соединения:

sudo lsof -i tcp

Только UDP-сокеты:

sudo lsof -i udp

Соединения в состоянии LISTEN (слушающие порты):

sudo lsof -i -s tcp:listen

Опция -s позволяет фильтровать по состоянию соединения (established, listen, close_wait и др.).

Соединения с конкретного или на конкретный IP-адрес:

# Все соединения с удалённого адреса 192.168.1.100
sudo lsof -i @192.168.1.100

# Все соединения на локальный интерфейс 192.168.1.5:80
sudo lsof -i @192.168.1.5:80

Шаг 6: Поиск файлов, открытых определённым пользователем

Чтобы увидеть все файлы, открытые пользователем apache или www-data:

sudo lsof -u apache

Можно указать нескольких пользователей: lsof -u user1,user2.

Шаг 7: Комбинирование фильтров (логическое И)

Фильтры в lsof по умолчанию объединяются через И (логическое умножение). Это очень мощно.

Пример: Найти все TCP-соединения (-i tcp), которые слушают (-s tcp:listen) и принадлежат процессу с именем nginx (-c nginx).

sudo lsof -i tcp -s tcp:listen -c nginx

Где:

  • -c <command> — фильтр по первым символам имени команды (можно использовать ^nginx для точного совпадения с начала строки).

Ещё пример: Какие файлы открывает пользователь postgres в каталоге /var/lib/postgresql?

sudo lsof -u postgres +D /var/lib/postgresql

Шаг 8: Полезные опции для удобного вывода

  • -n — не преобразовывать IP-адреса в имена хостов (ускоряет вывод).
  • -P — не преобразовывать номера портов в имена служб (порт 80 вместо http).
  • -F — вывод в формате, удобном для парсинга скриптами (каждая строка — поле, начинается с символа-идентификатора).
  • -t — вывод только PID (удобно для передачи в другие команды, например, kill).

Пример быстрой и чистой проверки слушающих портов:

sudo lsof -i -s tcp:listen -n -P

Шаг 9: Практический пример — остановка процесса, блокирующего порт

Допустим, вы запускаете веб-сервер на порту 8080 и получаете ошибку Address already in use.

  1. Найдите виновника:
    sudo lsof -i :8080
    

    В выводе смотрите PID (например, 12345) и COMMAND (например, java).
  2. Остановите процесс (если это не критичная служба):
    sudo kill 12345
    

    Если процесс не реагирует на SIGTERM (обычный kill), используйте принудительное завершение:
    sudo kill -9 12345
    
  3. Перезапустите ваш сервер. Порт теперь должен быть свободен.

Шаг 10: Поиск утечек файловых дескрипторов

Если процесс (особенно долгоживущий) открывает много файлов и не закрывает их, это может привести к исчерпанию лимита системы ( Too many open files).

  1. Посмотреть, сколько дескрипторов открыто у процесса:
    lsof -p <PID> | wc -l
    

    (Строка с COMMAND тоже учитывается, но для оценки порядок величин подходит).
  2. Посмотреть топ-процессов по количеству открытых файлов:
    sudo lsof | awk '{print $2}' | sort | uniq -c | sort -nr | head -20
    

    Эта команда:
    • awk '{print $2}' — вырезает второй столбец (PID).
    • sort | uniq -c — подсчитывает количество вхождений каждого PID.
    • sort -nr — сортирует по убыванию количества.
    • head -20 — показывает топ-20.

Проверка результата

После выполнения любой команды lsof проверьте, что вывод содержит ожидаемые данные:

  • Для поиска по файлу: В столбце NAME должен быть указан ваш путь.
  • Для поиска по порту: В столбце NAME должно быть *:порт или IP:порт, а в TYPEIPv4 или IPv6.
  • Для поиска по PID: В списке должен присутствовать указанный PID.

Если вывод пуст, это означает, что соответствующие ресурсы не открыты (файл не используется, порт не слушается) или вы запустили команду без sudo и не видите процессы других пользователей.

Возможные проблемы

Проблема 1: lsof: command not found

Причина: Пакет не установлен. Решение: Установите через менеджер пакетов вашего дистрибутива (см. Требования).

Проблема 2: Пустой вывод при поиске по порту (sudo lsof -i :80 ничего не показывает)

Причина 1: Никакой процесс действительно не слушает этот порт. Порт свободен. Причина 2: Вы ищете порт IPv6, а процесс слушает IPv4 (или наоборот). Попробуйте sudo lsof -i -P -n | grep :80 для общего поиска. Причина 3: Порт находится в состоянии TIME_WAIT (закрытое соединение, которое ещё не освободилось полностью). lsof по умолчанию не показывает такие сокеты. Используйте netstat -an | grep :80 или ss -ltnp для более полной картины.

Проблема 3: permission denied или недостаточно прав

Причина: Вы пытаетесь увидеть открытые файлы процесса, принадлежащего другому пользователю (особенно root), без sudo. Решение: Всегда используйте sudo для системного обзора: sudo lsof.

Проблема 4: Команда lsof работает очень медленно

Причина: Использование опции +D на большом каталоге или фильтрация по сложному шаблону. Решение:

  • Избегайте +D на корневых каталогах (/, /home). Ищите конкретные файлы.
  • Используйте более точные фильтры (-p, -u, -c) для уменьшения объема обрабатываемых данных.
  • Добавьте -n и -P для отключения преобразования имён (ускоряет работу).

Проблема 5: Не могу удалить файл, хотя lsof не показывает его использование

Причина 1: Файл удалён, но ещё открыт процессом. В lsof такой файл отобразится как (deleted) в конце строки NAME. Процесс продолжает писать в этот уже удалённый файловый дескриптор, занимая место на диске. Решение: Остановите процесс (kill), который держит дескриптор. Освобождение места на диске произойдёт автоматически после завершения процесса. Причина 2: Файл используется не процессом, а ядром (например, как swap-файл или корень смонтированной файловой системы). lsof может не показать такие системные использования. Используйте fuser -v /path/to/file или lsof /path/to/file | grep -v '(deleted)' для чистоты вывода.

Часто задаваемые вопросы

Что такое lsof и зачем он нужен?
Почему lsof выдает 'command not found'?
Как найти, какой процесс слушает определённый порт (например, 80)?
Чем lsof отличается от netstat или ss?

Полезное

Установка и проверка доступности
Базовый синтаксис и просмотр всех открытых файлов
Поиск файлов, открытых определённым процессом
Поиск процессов, открывших конкретный файл или каталог
Поиск процесса, слушающего сетевой порт
Фильтрация по протоколу (TCP/UDP) и состоянию