Битлента
Сетевые команды и утилиты5 мин чтения·

lsof: какие файлы открыл процесс и кто не даёт отключить диск

Как найти процесс, который держит файл или каталог, и список открытых файлов процесса через lsof. Ключи -p, -u, +D, +L1, ошибка device is busy.

Кратко

lsof показывает открытые файлы: lsof /путь находит процессы, которые держат файл, lsof -p PID перечисляет файлы процесса, lsof +L1 помогает найти удалённые, но ещё открытые файлы. Утилита есть в macOS и доступна в большинстве дистрибутивов Linux.

Когда пригодится список открытых файлов

В Unix-подобных системах открытым файлом считается не только документ на диске. Сетевое соединение, канал между процессами, устройство и каталог тоже представлены дескрипторами. Утилита lsof (list open files) выводит их все, и поэтому ею пользуются в нескольких типичных ситуациях.

Первая: диск или флешка не отключаются, а система пишет, что устройство занято (в англоязычных сообщениях device is busy). Значит, какой-то процесс держит файл или рабочий каталог на этом носителе. Вторая: на диске пропало место, хотя файлы удалены. Третья: программа жалуется на «too many open files», и нужно понять, сколько дескрипторов она использует. Четвёртая: нужно выяснить, какой процесс пишет в журнал.

Для задачи «кто слушает порт» есть отдельная страница про lsof -i, здесь же речь идёт о файлах и каталогах. В macOS lsof входит в систему, в Linux его может не оказаться в минимальной установке, тогда пакет ставится через менеджер пакетов дистрибутива.

Основные способы запуска

Ключи удобно запомнить по сценариям. Все примеры подставляйте со своими именами и путями.

  • lsof /путь/к/файлу показывает процессы, у которых этот файл открыт.
  • lsof -p 1234 перечисляет всё, что открыл процесс с номером 1234.
  • lsof -u имя_пользователя выводит открытые файлы одного пользователя.
  • lsof -c имя_программы отбирает процессы по началу имени команды.
  • lsof +D /путь/к/каталогу ищет открытые файлы внутри каталога рекурсивно. На больших деревьях это медленно, потому что lsof проверяет каждый элемент.
  • lsof +d /путь/к/каталогу смотрит только непосредственное содержимое каталога без вложенных.
  • lsof -t /путь выводит только номера процессов, без таблицы, что удобно для скриптов.

Условия по умолчанию объединяются через «или»: lsof -u user -c bash покажет и то и другое. Ключ -a превращает условия в «и». Так что lsof -a -u user -c bash оставит только процессы пользователя с именем bash.

Запуск от обычного пользователя, как правило, показывает подробности только по его собственным процессам, а полную картину по системе даёт запуск с правами администратора (sudo).

Как читать столбцы

Типичный вывод содержит столбцы COMMAND, PID, USER, FD, TYPE, DEVICE, SIZE/OFF, NODE и NAME. Нас чаще всего интересуют первый, второй, четвёртый и последний.

В столбце FD указан дескриптор. Значения cwd и txt означают рабочий каталог процесса и исполняемый файл программы. Числа с буквами, например 3r, 4w или 5u, означают файл, открытый на чтение, запись или чтение и запись. Значение mem относится к файлам, отображённым в память, например к библиотекам.

В столбце TYPE видно, что это: REG для обычного файла, DIR для каталога, CHR для символьного устройства, IPv4 и IPv6 для сетевых сокетов, unix для локальных сокетов. В NAME находится путь или описание соединения.

В Linux рядом с путём может стоять пометка (deleted): файл уже удалён из каталога, но процесс продолжает им пользоваться. Это не ошибка вывода, а нормальное состояние, которое объясняет следующий сценарий.

🛡️ Остались проблемы с соединением?
Можно пользоваться постоянно: российские приложения работают, включать и выключать ничего не нужно. Без карты и регистрации, настройка за пару минут.
Попробовать бесплатно

Место не освобождается после удаления файла

Классический случай: вы удалили огромный журнал, а команда df показывает, что место не вернулось. Причина в том, что файловая система освобождает данные только когда на файл не осталось ни одной ссылки, включая открытые дескрипторы. Пока процесс держит файл, блоки остаются занятыми, а имя в каталоге уже исчезло. Утилиты вроде du такой файл не видят, потому что просматривают только каталоги.

Найти такие файлы поможет ключ +L1: lsof +L1 выводит открытые файлы, у которых число ссылок меньше одной, то есть удалённые, но ещё используемые. По столбцу SIZE/OFF видно размер, по PID и COMMAND понятно, кто держит.

Дальше есть варианты. Корректно перезапустите или завершите процесс штатными средствами службы, и место освободится. Если вы остановить его не можете, у многих программ есть команда переоткрытия журнала. Принудительное обрезание файла через /proc/PID/fd/N в Linux возможно, но это приём для опытных администраторов, и применять его на чужих системах без понимания последствий не стоит.

Подробности о том, как свободное место и занятое место считаются разными инструментами, и о поиске крупных каталогов см. отдельные страницы про du и free.

Как узнать, сколько дескрипторов у процесса

Сообщение «too many open files» означает, что процесс упёрся в лимит числа открытых дескрипторов. Лимит задаётся для сеанса командой ulimit -n, а для служб ещё и настройками системы. Чтобы увидеть текущее потребление, посчитайте строки вывода: lsof -p 1234 | wc -l. Результат включает строку заголовка и записи mem, поэтому это оценка с погрешностью, а не точное число дескрипторов.

В Linux точнее и быстрее смотреть каталог /proc/1234/fd: количество элементов в нём равно числу дескрипторов. В macOS каталога /proc нет, поэтому там остаётся lsof.

Если число стабильно растёт со временем, возможно, программа не закрывает файлы или соединения. Это уже вопрос к разработчику или к настройкам службы. Для администратора первый шаг: собрать вывод lsof -p в два момента времени и сравнить, какого типа записей стало больше, файлов или сокетов.

Помните про ограничения: lsof может работать медленно на системах с очень большим числом процессов, а часть сведений скрыта от обычного пользователя. Когда нужно быстро проверить только порты, используйте ss в Linux, как описано на странице про ss -tulpn.

Короткая шпаргалка по сценариям

Чтобы не искать ключи каждый раз, соберите их по задачам.

  • Не отключается флешка: lsof +D /точка/монтирования, найдите процесс и закройте программу, которая держит файл.
  • Пропало место после удаления: lsof +L1, найдите удалённые, но открытые файлы.
  • Что делает процесс: lsof -p PID.
  • Что открыто у пользователя: lsof -u имя.
  • Только номера процессов для скрипта: lsof -t /путь.

Перед завершением процессов, найденных через lsof, убедитесь, что вы понимаете, что они делают. Принудительное закрытие программы, пишущей на диск, может привести к потере несохранённых данных.

🛡️ Остались проблемы с соединением?
Можно пользоваться постоянно: российские приложения работают, включать и выключать ничего не нужно. Без карты и регистрации, настройка за пару минут.
Попробовать бесплатно
lsofфайлыпроцессыlinuxmacos

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

Читайте также