Как узнать, какие файлы используются процессом Linux

Обновлено: 24.11.2024

Теперь ваша компания может нанять меня
(Элвина Александра) для небольших побочных проектов Scala и Flutter.

Свяжитесь со мной по адресу (al) Valleyprogramming (dot) com для получения подробной информации.

Часто задаваемые вопросы об открытых файлах Linux. Можете ли вы поделиться несколькими примерами того, как отображать открытые файлы в системе Linux (например, как использовать команду lsof)?

фон команды lsof

Команда Linux lsof выводит информацию о файлах, открытых процессами, работающими в системе. Команда lsof — это аббревиатура от «список открытых файлов». В этой статье я приведу несколько примеров команд lsof.

Я предполагаю, что вы вошли в систему как пользователь root

Еще одно замечание: в этих примерах я предполагаю, что вы вошли в систему как привилегированный пользователь Unix/Linux. В противном случае вывод команды lsof может быть значительно ограничен. Если вы вошли в систему как пользователь без полномочий root, либо su для получения root, либо используйте sudo для запуска этих команд.

Базовые примеры команд lsof в Linux

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

В моей текущей системе macOS, которая работает в течение длительного времени, это показывает много открытых файлов, 1582, если быть точным:

Обратите внимание, что мне не нужно было входить в систему как пользователь root, чтобы увидеть эту информацию в моей системе Mac.

Добавление команды head в lsof показывает, как выглядит часть этого вывода:

Общие параметры lsof

Как уже упоминалось, эти детали занимают 1582 строки, поэтому полезно иметь какой-то способ отсеять эти выходные данные, будь то использование команды grep или некоторых параметров lsof, показанных ниже.

Эта команда выводит список всех открытых файлов, принадлежащих PID (идентификатору процесса) 11925:

Эта команда выводит список всех открытых файлов, принадлежащих процессам, принадлежащим пользователю с именем "al":

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

Резюме: примеры команд lsof в Linux

Я надеюсь, что эти примеры команд Linux lsof были вам полезны. Как видите, команду lsof можно использовать для создания списка открытых файлов в вашей системе Unix и Linux с различными параметрами командной строки для различных обстоятельств.

Для получения дополнительной информации о команде lsof см. блок "Связанные" на этой странице, перейдите по этой ссылке, чтобы просмотреть результаты поиска команды lsof на этом веб-сайте, или оставьте примечание в разделе "Комментарии" ниже.

Если у вас есть несколько лет опыта работы с экосистемой Linux и вы хотите поделиться этим опытом с сообществом, ознакомьтесь с нашими Правилами участия.

1. Введение

Иногда, когда мы пытаемся получить доступ к файлу, мы можем увидеть сообщение файл занят. Это означает, что в системе запущен процесс, который использует файл, сохраняя его открытым либо для чтения, либо для записи. Когда это происходит, иногда нам нужно обнаружить процесс, который использует файл.

В этом руководстве мы рассмотрим, как найти процесс, использующий файл.

2. Методы и команды для поиска процесса

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

2.1. Команда fuser

Начнем с команды fuser, которая выводит список процессов, использующих файлы или сокеты. Его также можно использовать для уничтожения процесса. Мы можем использовать его с параметром -v для получения подробного вывода:

Как мы видим, в данном случае к файлу обращается процесс less. Команда fuser возвращает PID, пользователя, вызвавшего процесс, и состояние файла.

Выполнение команды с параметром -k уничтожит процесс, который она найдет. Давайте попробуем убить процесс less с помощью SIGKILL, используя PID 24815:

Допустим, к тому же файлу обращается vi. Когда мы запустим ту же команду, ничего не будет возвращено, потому что vi открывает файл, считывает его содержимое в память и закрывает его. Ядро уже выполнило свою работу, поэтому информация о файле недоступна.

Однако мы можем попытаться найти процесс, проанализировав и угадав вывод fuser -cv text.txt. Ответ представляет собой список всех процессов, которые обращаются к файлам в той же файловой системе. В этом случае последняя строка вывода — это искомый процесс. Однако так может быть не всегда.

Выполнение команды с параметром -k может убить все процессы, использующие указанный файл или каталог, поэтому используйте его с осторожностью.

2.2. Команда lsof

Команда lsof может возвращать список открытых файлов.Чтобы сузить результаты и сохранить строку заголовка, мы будем использовать ее с командами head и grep. Предполагая, что vi все еще работает, давайте попробуем:

Команда lsof возвращает имя процесса, PID и пользователя, запускающего процесс. Если у процесса есть потоки, мы увидим их идентификационный номер, TID, с командой задачи. Поле FD может состоять из трех частей: дескриптор файла (в нашем случае 4) — первая, символ mode — вторая (u означает файл доступен для чтения и записи), а символ lock — третий.

Давайте посмотрим на вывод, когда команда less обращается к файлу вместо vi:

В этом случае мы видим, что файл открыт для чтения с FD = 4r.

Однако, как и в случае с fuser, если мы используем vi для редактирования файла, lsof не покажет его, как в использовать.

Команда имеет множество опций. Например, -t дает только идентификаторы процессов без заголовка, что делает его полезным при написании скриптов.

lsof очень похож на fuser, за исключением того, что он не может завершать процессы. Однако, поскольку lsof также дает нам PID, мы можем присоединиться к нему с помощью команды kill:

Чтобы обнаружить PID всех процессов, использующих файлы в каталоге и ниже, мы можем рекурсивно сканировать его с помощью +D.

Кроме того, lsof часто используется для поиска всех файлов, открытых данным (по PID) процессом:

2.3. Получение информации из ядра напрямую

Еще один способ определить, какой процесс используется в файле, — прямой доступ к ядру. Ядро хранит данные в папке /proc. Информация о процессе находится в каталоге /proc/

<р>. Он содержит записи для всего, что открывается файлом процесса, названным по его файловому дескриптору, который связан с фактическим файлом.

Поэтому нам нужно использовать только команду ls:

Давайте улучшим эти результаты с помощью скрипта, который печатает только PID:

Для каждого PID в каталоге /proc/pid мы копаем в каталоге, а затем в подкаталоге, fd. Затем читаем ссылки. Если эта ссылка является файлом, мы печатаем его имя. Наконец, загрузите результат с заданным именем файла.

Если мы сохраним этот скрипт как mylsof и разрешим ему выполняться (chmod u+x mylsof), мы сможем использовать его для решения нашей проблемы:

Получение информации из ядра работает всегда, даже в системах с BusyBox. Это может помочь, если в системе нет ни lsof, ни fuser.

3. Заключение

В этой статье мы рассмотрели процесс, который обращается к файлу. Мы начали с команды fuser, а затем рассмотрели использование lsof. Мы также заглянули в ядро, чтобы выбрать необходимые данные.

Если у вас есть несколько лет опыта работы с экосистемой Linux и вы хотите поделиться этим опытом с сообществом, ознакомьтесь с нашими Правилами участия.

Я попытался удалить файл в Linux с помощью команды rm -rf имя_файла, но получил ошибку:

Как узнать, какой процесс использует этот файл?

4 ответа 4

Вы можете использовать команду fuser, например:

Вы получите список процессов, использующих файл.

Вы можете использовать различные флаги, чтобы получить более подробный вывод.

Дополнительную информацию можно найти в статье о фьюзере в Википедии или на справочных страницах.

@khris, возможно, не все реализации фьюзера одинаковы или работают одинаково. Даже если параметр -i определен в POSIX, конкретная реализация, которую вы используете, не обязательно имеет те же параметры, что и описанные в статье в Википедии. Например, прямо сейчас я использую AIX, и доступный в этой системе блок фьюзера также не имеет опции -i.

По какой-то причине ни fuser, ни lsof не работали у меня на гостевой виртуальной машине. Этот ответ спас меня.

Ответ @jim правильный - вам нужен фьюзер.

Дополнительно (или в качестве альтернативы) вы можете использовать lsof для получения дополнительной информации, включая имя пользователя, на случай, если вам потребуется разрешение (без выполнения дополнительной команды) для завершения процесса. (Хотя, конечно, если вы хотите убить процесс, fuser может сделать это с опцией -k. Вы можете настроить fuser на использование других сигналов с опцией -s — подробности см. на справочной странице.)

Например, если хвост -F /etc/passwd запущен в одном окне:

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

Для пользователей без фьюзера:

Хотя мы можем использовать lsof, есть и другой способ, например, мы можем запросить саму файловую систему /proc, в которой перечислены все открытые файлы по всем процессам.

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

l-wx------. 1 root root 64 15 августа 02:56 /proc/5026/fd/4 -> /var/log/filename.log

Из вывода можно использовать идентификатор процесса в утилите, такой как ps, чтобы найти имя программы

Я хочу определить, какой процесс владеет файлом блокировки. Файлы блокировки — это просто созданный файл с определенным именем.

Итак, как определить, в каком процессе в Linux открыт тот или иной файл? Предпочтительно использовать однострочный тип или конкретное инструментальное решение для Linux.

5 ответов 5

Для этого также можно использовать термоблок:

Fuser странно себя ведет с кодами выхода. он возвращает 1 код выхода с двумя состояниями: A/какая-то внутренняя ошибка, проверенный файл не найден и т. д., B/процесс не открыл указанный файл. В ситуации A/ на его выход выводится сообщение об ошибке. К сожалению, когда файл доступен и чем-то открыт, вывод генерируется, но с кодом выхода 0. Было бы лучше, если фьюзер будет выходить с тремя кодами, а не с двумя, как сейчас. lsoft немного хуже, потому что работает медленнее.

По сути, это тот же шаблон, которому следует ls — он возвращает код выхода 2, если есть ошибка (например, указана недопустимая опция) или файл не найден (и 0, если он успешно сообщает информацию).

В большинстве систем Linux lsof NAME выполняет эту работу:

@JoseLSegura: Я предполагаю, что вы достаточно находчивы, чтобы ответ «затем установите lsof» был для вас бесполезен. Можешь подробнее рассказать о своей проблеме? Если у вас нет root, у вас, вероятно, нет привилегий, чтобы узнать, не открыл ли файл другой пользователь.

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

Открытие файла не является блокировкой, потому что, если каждый процесс должен сначала проверить, открыт ли файл, и не продолжать, если он открыт, или создать/открыть его, если это не так, то два процесса вполне могут проверить это одновременно. , оба обнаруживают, что он не открыт, затем оба создают или открывают его.

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

Если ваш процесс блокировки представляет собой сценарий оболочки, который будет работать как демон, вы можете получить этот эффект, используя umask , параметр для каждого процесса, который устанавливает разрешения, с которыми создаются новые файлы:

Это также записывает PID процесса-владельца в файл, что решает другую вашу проблему: cat /var/lock/foo Что касается конкретного вопроса «В каких процессах открыт этот файл?», это может быть полезно, когда вы хотите размонтировать файловую систему, но не может, потому что в каком-то процессе открыт файл. Если у вас нет этих команд, вы можете запросить /proc как root:

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