Як використовувати команду lsof Linux


Аналіз відкритих файлів у Linux за допомогою команди lsof

У світі Linux, де майже все представлено як файл, розуміння того, як ці “файли” використовуються, є ключовим. Ця стаття пояснює, як використовувати команду lsof для відстеження різних пристроїв та процесів, які система розглядає як файли.

Концепція “все є файлом” у Linux

Поширена фраза “все в Linux є файлом” має глибокий сенс. Файл, по суті, – це послідовність байтів. Коли дані зчитуються або надсилаються, вони утворюють потік байтів. Так само, при записі, файл приймає потік байтів.

Багато системних компонентів, такі як клавіатури, мережеві з’єднання, принтери та процеси, також працюють з потоками байтів. Таким чином, Linux розглядає ці пристрої як файли, що спрощує їх обробку за допомогою уніфікованих інструментів та API.

Цей підхід до дизайну операційної системи Unix виявився дуже ефективним. Він дозволив створити невеликий, але потужний набір утиліт та інтерфейсів для взаємодії з різноманітними ресурсами.

Файли, що зберігаються на жорсткому диску, – це звичайні файли, з якими ми працюємо щодня. Команда `ls` дозволяє нам переглядати їх вміст та отримувати інформацію. Але як дізнатися про інші об’єкти, які Linux розглядає як файли? Тут на допомогу приходить команда `lsof`, що означає “list open files”. Вона показує всі відкриті файли, включаючи не тільки дискові, а й багато інших ресурсів.

Використання команди lsof

Багато процесів, які `lsof` відображає, належать користувачу root, тому для повноцінної роботи з командою `lsof` потрібно використовувати `sudo`.

Оскільки вивід `lsof` може бути дуже великим, варто одразу передати його до утиліти `less` для зручного перегляду:

sudo lsof | less

Користувачі GNOME можуть побачити попередження при запуску `lsof`:

lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
Output information may be incomplete.

Це попередження з’являється через спробу `lsof` обробити файлову систему GNOME Virtual File System (GVFS). GVFS працює як проміжний шар між GNOME та ядром. Оскільки доступ до цих файлових систем обмежений, ви можете проігнорувати це попередження.

Вивід `lsof` складається з багатьох стовпців. Ось крайні ліві стовпці:

А ось крайні праві стовпці:

Пояснення стовпців lsof

Не всі стовпці є актуальними для кожного типу файлу. Іноді деякі стовпці можуть залишатися порожніми.

Команда Назва команди, що відкрила файл.
PID Ідентифікатор процесу, що відкрив файл.
TID Ідентифікатор потоку (завдання). Якщо стовпець порожній, це означає, що це процес, а не потік.
Користувач Ім’я або ідентифікатор користувача, якому належить процес, або хто володіє каталогом в /proc, де lsof отримує інформацію про процес.
FD Опис дескриптора файлу (див. деталі нижче).
Тип Тип вузла файлу.
Пристрій Номер пристрою, іноді адреса ядра, або інші ідентифікатори пристрою.
Size/Off Розмір файлу або зміщення в байтах.
Вузол Номер вузла файлу або інод файлу NFS. Може бути STR для потоку, IRQ, або номер інода пристрою.
Ім’я Назва точки монтування та файлової системи.

Розшифровка стовпця FD

Стовпець FD (File Descriptor) показує дескриптор файлу. Детальний список дескрипторів можна знайти в документації до lsof.

Дескриптор файлу складається з трьох частин: сам дескриптор, символ режиму та символ блокування. Деякі типові дескриптори:

  • cwd: Поточний робочий каталог.
  • err: Помилка (інформація в NAME).
  • ltx: Текст спільної бібліотеки.
  • m86: Файл, відображений DOS Merge.
  • mem: Файл, відображений в пам’ять.
  • mmap: Пристрій, відображений в пам’ять.
  • pd: Батьківський каталог.
  • rtd: Кореневий каталог.
  • txt: Текст програми.
  • Число: Сам дескриптор файлу.

Символ режиму може бути:

  • r: Доступ для читання.
  • w: Доступ для запису.
  • u: Доступ для читання та запису.
  • ‘ ‘: Режим невідомий (без блокування).
  • -: Режим невідомий (є блокування).

Символ блокування може бути:

  • r: Блокування читання частини файлу.
  • R: Блокування читання всього файлу.
  • w: Блокування запису частини файлу.
  • W: Блокування запису всього файлу.
  • u: Блокування читання та запису будь-якої довжини.
  • U: Невідомий тип блокування.
  • ‘ ‘: Блокування відсутнє.

Значення стовпця TYPE

Стовпець TYPE має понад 70 різних значень. Ось деякі з найпоширеніших:

  • REG: Звичайний файл.
  • DIR: Каталог.
  • FIFO: Канал FIFO.
  • CHR: Спеціальний файл символів.
  • BLK: Спеціальний блоковий файл.
  • INET: Інтернет-сокет.
  • unix: UNIX-сокет.

Перегляд процесів, що відкрили файл

Щоб побачити процеси, що використовують певний файл, вкажіть ім’я цього файлу як аргумент lsof. Наприклад, для перегляду процесів, що працюють з файлом `kern.log`, використайте команду:

sudo lsof /var/log/kern.log

У прикладі вище `lsof` показує процес `rsyslogd`, який використовується системним журналом.

Список файлів, відкритих з каталогу

Щоб переглянути всі файли, відкриті з певного каталогу, використовуйте опцію `+D` та назву каталогу. Наприклад, для каталогу `/var/log/` команда буде виглядати так:

sudo lsof +D /var/log/

Команда покаже всі файли, які були відкриті в каталозі `/var/log/`.

Аналогічно для каталогу `/home`:

sudo lsof +D /home

Зверніть увагу, що список файлів може виглядати по-різному через різну довжину опису в стовпцях.

Файли, відкриті процесом

Щоб переглянути файли, відкриті певним процесом, використовуйте опцію `-c` (command) та ім’я процесу. Можна вказати кілька пошукових критеріїв одночасно. Наприклад:

sudo lsof -c ssh -c init

Вивід `lsof` показує файли, що використовуються процесами `ssh` або `init`.

Файли, відкриті користувачем

Використання опції `-u` (user) дозволяє фільтрувати файли, відкриті певним користувачем. У прикладі нижче переглянемо файли, відкриті користувачем `mary`:

sudo lsof -u mary

Список включає всі файли, відкриті процесами, що належать користувачу `mary`.

Виключення файлів, відкритих користувачем

Щоб виключити файли, відкриті конкретним користувачем, використовуйте оператор `^`. Наприклад, для виключення користувача `mary` зі списку в каталозі `/home`:

sudo lsof +D /home -u ^mary

Список файлів у каталозі `/home` тепер не включає файли, відкриті користувачем `mary`.

Список файлів за ідентифікатором процесу

Використовуйте параметр `-p` (process) та ідентифікатор процесу, щоб вивести список файлів, відкритих цим процесом:

sudo lsof - p 4610

Команда виведе всі файли, відкриті процесом з ідентифікатором `4610`.

Перелік ідентифікаторів процесів, що відкрили файл

Опція `-t` (terse) виводить лише ідентифікатори процесів, що відкрили вказаний файл. Наприклад:

sudo lsof -t /usr/share/mime/mime.cache

Ви отримаєте простий список ідентифікаторів процесів.

Використання пошуку “І” та “АБО”

Давайте знайдемо файли, відкриті користувачем `mary`, пов’язані з процесами `ssh`. На перший погляд, можна спробувати таку команду:

sudo lsof -u mary -c ssh

Але вивід може містити не тільки файли користувача `mary`, але і файли, відкриті root.

Причина в тому, що `lsof` за замовчуванням використовує логіку “АБО”, тобто виводить файли, що відповідають будь-якому з наданих критеріїв. Щоб використовувати логіку “І”, додайте опцію `-a` (and):

sudo lsof -u mary -c ssh -a

Тепер список включає лише файли, відкриті користувачем `mary` та пов’язані з `ssh`.

Автоматичне оновлення виводу

Опція `+|-r` (repeat) дозволяє lsof оновлювати вивід через заданий інтервал. `+r` – вивід оновлюється, доки є що показувати, `-r` – оновлення триватиме, поки не перервете його вручну. Після опції `r` вкажіть кількість секунд між оновленнями. Наприклад:

sudo lsof -u mary -c ssh -a -r5

Після виводу списку файлів з’явиться пунктирна лінія, що сигналізує про початок автоматичного оновлення.

Відображення файлів, пов’язаних з мережею

Використовуйте опцію `-i` (internet) для перегляду файлів, відкритих процесами, що пов’язані з мережею:

lsof -i

З’явиться список файлів, відкритих мережевими процесами.

Файли мережі за ідентифікатором процесу

Використовуйте комбінацію `-i`, `-a` та `-p` для виведення файлів мережі, що належать певному процесу. Наприклад, для процесу з ідентифікатором `606`:

sudo lsof -i -a -p 606

Список покаже файли, відкриті процесом з ідентифікатором `606`, через мережеве з’єднання.

Мережеві файли, пов’язані з командами

Для пошуку мережевих файлів, відкритих певними процесами, використовуйте комбінацію `-i`, `-a`, та `-c`. Наприклад, для `ssh`:

lsof -i -a -c ssh

Ви отримаєте перелік файлів, відкритих `ssh` через мережу.

Мережеві файли за номером порту

Для пошуку мережевих файлів, відкритих на певному порту, використовуйте опцію `-i :номер_порту`. Наприклад, для порту `22`:

lsof -i :22

Список покаже всі файли, відкриті через порт `22` (зазвичай для SSH).

Мережеві файли за протоколом

Для пошуку мережевих файлів, що використовують певний протокол, використовуйте `-i протокол`. Наприклад, для протоколу TCP:

sudo lsof -i tcp

Ви отримаєте перелік файлів, відкритих за протоколом TCP.

Підсумок

Ми розглянули лише базові приклади використання команди `lsof`. Насправді, вона має набагато більший функціонал, який можна вивчити за допомогою сторінки довідки (man). `lsof` є потужним інструментом для аналізу файлів і процесів у Linux, що дозволяє отримати глибоке розуміння роботи системи. Детальна документація допоможе вам освоїти всі можливості цієї команди.