lsof -p PID против lsof | grep PID

Вопрос или проблема

Я не понимаю вывод команды 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 потенциально покажет дублированные записи для каждого потока.

https://support.datastax.com/hc/en-us/articles/209826153-lsof-shows-Cassandra-is-holding-a-large-amount-of-files-open

Я пробовал это на своей системе, и обе команды генерируют один и тот же список. Я предлагаю вам попробовать обе команды последовательно несколько раз, просто чтобы убедиться, что состояние процесса стабильно. Согласно странице 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.

Оцените материал
Добавить комментарий

Капча загружается...