Вопрос или проблема
Я не понимаю вывод команды lsof.
Когда я пишу
lsof -p PID
Я получаю 4 строки, а когда пишу
lsof | grep PID
Я получаю сотни строк.
Не должен ли он возвращать один и тот же результат?
Спасибо за ваши ответы. Вот вывод. Похоже, это подпроцесс или что означают эти задачи?
lsof -p 29076
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 29076 pr cwd unknown /proc/29076/cwd (readlink: Permission denied)
java 29076 pr rtd unknown /proc/29076/root (readlink: Permission denied)
java 29076 pr txt unknown /proc/29076/exe (readlink: Permission denied)
java 29076 pr NOFD /proc/29076/fd (opendir: Permission denied)
lsof |grep 29076|head -20
java 29076 pr cwd unknown /proc/29076/cwd (readlink: Permission denied)
java 29076 pr rtd unknown /proc/29076/root (readlink: Permission denied)
java 29076 pr txt unknown /proc/29076/exe (readlink: Permission denied)
java 29076 pr NOFD /proc/29076/fd (opendir: Permission denied)
java 29076 300 pr cwd unknown /proc/29076/task/300/cwd (readlink: Permission denied)
java 29076 300 pr rtd unknown /proc/29076/task/300/root (readlink: Permission denied)
java 29076 300 pr txt unknown /proc/29076/task/300/exe (readlink: Permission denied)
java 29076 300 pr NOFD /proc/29076/task/300/fd (opendir: Permission denied)
java 29076 329 pr cwd unknown /proc/29076/task/329/cwd (readlink: Permission denied)
java 29076 329 pr rtd unknown /proc/29076/task/329/root (readlink: Permission denied)
java 29076 329 pr txt unknown /proc/29076/task/329/exe (readlink: Permission denied)
java 29076 329 pr NOFD /proc/29076/task/329/fd (opendir: Permission denied)
java 29076 330 pr cwd unknown /proc/29076/task/330/cwd (readlink: Permission denied)
java 29076 330 pr rtd unknown /proc/29076/task/330/root (readlink: Permission denied)
java 29076 330 pr txt unknown /proc/29076/task/330/exe (readlink: Permission denied)
java 29076 330 pr NOFD /proc/29076/task/330/fd (opendir: Permission denied)
java 29076 331 pr cwd unknown /proc/29076/task/331/cwd (readlink: Permission denied)
java 29076 331 pr rtd unknown /proc/29076/task/331/root (readlink: Permission denied)
java 29076 331 pr txt unknown /proc/29076/task/331/exe (readlink: Permission denied)
java 29076 331 pr NOFD /proc/29076/task/331/fd (opendir: Permission denied)
Без того, чтобы видеть фактический вывод, трудно сказать, что именно происходит, но я предполагаю, что это вызвано тем, что команда lsof -p PID
просто выводит файлы, которые открыты указанным PID, в то время как lsof | grep PID
выводит любые строки, в которых «PID» находится где угодно в строке. Например, если вы ищете PID=123, то ваш параметр grep
также выведет строки для PID 1231, 1232, 1233 и т.д., а также любые файлы, которые находятся в папках с 123 в любом месте их полного пути.
ИЗМЕНЕНИЕ:
В вашем конкретном примере разница заключается в том, что lsof
игнорирует файлы, открытые потоком. Если вы посмотрите на вывод в примере с grep
, третья колонка — это «TID» или идентификатор потока. Строки без TID соответствуют тому, что вы видели, когда использовали опцию -p
. Строки с TID (т.е. строки, открытые другими потоками) — это лишние.
lsof – список открытых файлов, попробуйте прочитать страницу man для lsof #man lsof
lsof -p PID
перечисляет открытые файлы, связанные с идентификатором процесса PID.
В отсутствие каких-либо параметров, lsof перечисляет все открытые файлы, принадлежащие всем активным процессам. Когда вы делаете lsof | grep PID
, это перечисляет все открытые файлы, принадлежащие всем активным процессам, и выполняет поиск по номеру PID, который может совпадать с самим PID, а также в любом месте, где PID появляется как часть других PIDs и может быть дочерним процессом PID и так далее.
Поэтому, если вы хотите использовать lsof | grep PID
, то вы должны точно сопоставить PID, как полное слово lsof | grep -w PID
, но это все равно приведет к большему количеству строк, если у PID есть другие дочерние процессы.
Некоторые версии lsof включают идентификатор потока. Это можно определить по заголовку колонки TID, который видно в выводе. Такой вывод приведет к дублированию записей, поскольку lsof потенциально покажет дублированные записи для каждого потока.
Я пробовал это на своей системе, и обе команды генерируют один и тот же список. Я предлагаю вам попробовать обе команды последовательно несколько раз, просто чтобы убедиться, что состояние процесса стабильно. Согласно странице man и вашим выводам, это единственное объяснение, которое я могу предложить.
Я знаю, что вопрос старый, но у меня была та же проблема. Проблема в том, что «потоки» не перечислены под своим родителем. Мое решение было простым
lsof -a -K -p $(pidof -s <service>)
-a
для «и» (в противном случае по умолчанию — «или», и это покажет все процессы)
-K
для «перечислить задачи/потоки»
Например:
lsof -a -K -p $(pidof -s NetworkManager) | wc -l
даёт 292
, тогда как
lsof -p $(pidof -s NetworkManager) | wc -l
даёт только 98
.
Вышеуказанный вывод будет виден, если процесс за PID не принадлежит пользователю, выполняющему lsof
. Вам, вероятно, нужно быть root, чтобы получить желаемый вывод.
Ответ или решение
Команда lsof
(list open files) используется для отображения файлов, открытых процессами в операционной системе. В вашем вопросе есть два различных способа использования этой команды для анализа открытых файлов для процесса с определенным PID (идентификатором процесса). Давайте подробнее разберем различия между командами lsof -p PID
и lsof | grep PID
.
1. Основная функция lsof
Команда lsof
предоставляет возможность увидеть, какие файлы открыты в системе, кто их открыл и другую связанную информацию. Это особенно полезно для системных администраторов и разработчиков для диагностики проблем с производительностью и ресурсами.
2. lsof -p PID
Когда вы используете lsof -p PID
, вы указываете непосредственно идентификатор процесса, для которого хотите получить список открытых файлов. Это значит, что команда:
- Покажет только те файлы, которые были открыты непосредственно процессом с заданным PID.
- Не охватывает открытые файлы дочерних потоков (threads) данного процесса, если только вы не используете дополнительные параметры для их отображения.
Из спецификации вывода вашего примера видно, что команда вернула всего 4 строки. Это указывает на то, что процесс с указанным PID действительно открыл только 4 файла или директории, которые и отобразились.
3. lsof | grep PID
В случае использования lsof | grep PID
, команда lsof
сначала предоставляет список всех открытых файлов для всех процессов в системе, а затем передает этот список в grep
, который ищет строки, содержащие указанный вами PID. Поскольку параметр grep
не ограничивает поиск только строками, соответствующими PID указанного процесса, это может привести к следующим исходам:
- Все строки, содержащие совпадение с PID — это не только строки для процесса 29076, но и могут включать строки для дочерних процессов, если они, например, используются в названии процесса.
- В результате вы можете увидеть множество строк, которые не обязательно относятся к вашему процессу, и именно это объясняет, почему вы получаете сотни строк в выводе
lsof | grep PID
.
4. Объяснение вашего вывода
Ваши выводы показывают явные признаки того, что вы видите файловые дескрипторы как для основного процесса, так и для его дочерних потоков. Вы можете заметить, что среди строк, возвращаемых grep
, есть строки с дополнительными TID (идентификаторы потоков), которые могут относиться к другим потокам.
5. Рекомендуемые действия
Если вам нужно получить четкий и полный список открытых файлов для процесса и всех его потоков, вы можете использовать следующий вариант:
lsof -a -p PID -K
Здесь:
-a
означает "и" (вывод только тех файлов, которые одновременно открыты данным процессом и подключенными потоками).-K
— вывод открытых файлов для потоков.
Если требуется отобразить файлы, открываемые только основным процессом, используйте lsof -p PID
, как вы делали изначально.
Заключение
Ваша проблема связана с тем, что команды lsof -p PID
и lsof | grep PID
имеют различный подход к выбору файловых дескрипторов. Первый вариант нацелен конкретно на процесс, тогда как второй — на общий вывод, из которого могут появляться многократные совпадения. Чтобы избежать путаницы и получить желаемую информацию, всегда учитывайте контекст использования команд и старайтесь ограничивать вывод с помощью различных параметров lsof
.