Команда lsof

Команда lsof (List Of Open Files) позволяет задействовать одноименную утилиту, предназначенную для вывода информации об открытых файлах и сетевых сокетах. Как известно, в Linux и Unix все является файлом, поэтому она может использоваться для получения информации не только об обычных открытых файлах, но также об открытых директориях, файлах блочных и символьных устройств, а также файлах именованных каналов и сокетов домена Unix. Данная команда может оказаться крайне полезной при необходимости поиска процессов, которые блокируют файлы таких устройств, как звуковая карта или DVB-карта. Команда выводит результаты в формате списка, который может фильтроваться с помощью утилиты grep.

Базовый синтаксис команды выглядит следующим образом:

$ lsof [параметры] [имя пользователя или процесса]

Утилита может вызываться как без параметров, так и с ними. В случае указания имени пользователя и использования параметра -u она будет выводить список файлов, открытых пользователем с указанным именем. В случае указания имени процесса и использования параметра -c она будет выводить список файлов, открытых процессом с указанным именем, причем вместо имени процесса может использоваться его числовой идентификатор. В случае указания пути и использования параметра -D она будет выводить список открытых файлов из данной директории. При этом стоит помнить о префиксе ^, который позволяет выполнить противоположную операцию — вывести список файлов, открытых всеми кроме пользователя с указанным именем, всеми, кроме процесса с указанным именем или идентификатором или из все, кроме указанной директории. Также стоит помнить о параметре -i, позволяющем вывести список открытых сетевых сокетов.

Что касается списка открытых файлов, то он содержит следующие колонки:

  • COMMAND — имя команды
  • PID — идентификатор процесса
  • USER — имя пользователя
  • FD — тип файлового дескриптора
  • TYPE — тип структуры inode, ассоциированной с файлом
  • DEVICE — идентификаторы major и minor ассоциированного устройства
  • SIZE/OFF — размер файла / сдвиг в файле
  • NODE — идентификатор структуры inode
  • NAME — путь к файлу

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

Примеры использования

Вывод списка всех открытых файлов

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

# sudo lsof
COMMAND    PID  TID TASKCMD               USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
systemd      1                            root  cwd       DIR               8,24      4096          2    /
systemd      1                            root  rtd       DIR               8,24      4096          2    /
systemd      1                            root  txt       REG               8,24   1620224     947274    /lib/systemd/systemd
…

Список является слушком длинным. Вы можете отфильтровать его с помощью grep:

# lsof | grep brave
brave-bro 4142                            alex  cwd       DIR               8,52     36864    3407873     /home/alex
brave-bro 4142                            alex  rtd       DIR               8,24      4096          2     /
brave-bro 4142                            alex  txt       REG               8,24   1183448    1044538     /bin/bash
brave-bro 4142                            alex  mem       REG               8,24  14537056    1179034     /usr/lib/locale/locale-archive
…

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

Вывод списка всех файлов, открытых пользователм

Для вывода списка всех файлов, открытых пользователем, достаточно указать имя пользователя после параметра -u:

# lsof -u alex
COMMAND    PID  TID TASKCMD               USER   FD      TYPE             DEVICE  SIZE/OFF       NODE NAME
systemd   2263                            alex  cwd       DIR               8,24      4096          2    /
systemd   2263                            alex  rtd       DIR               8,24      4096          2    /
systemd   2263                            alex  txt       REG               8,24   1620224     947274    /lib/systemd/systemd
systemd   2263                            alex  mem       REG               8,24   1369352     918007    /lib/x86_64-linux-gnu/libm-2.31.so
…

Если вы хотите ознакомиться со списком файлов, открытых вашими процессами, вы можете не запускать утилиту от лица суперпользователя.

Вывод списка открытых сетевых сокетов

Для вывода списа открытых сетевых сокетов достаточно использовать параметр -i утилиты:

# lsof -i
COMMAND    PID            USER   FD   TYPE DEVICE  SIZE/OFF NODE NAME
systemd-r 1098 systemd-resolve  12u   IPv4  30038       0t0  UDP localhost:domain 
systemd-r 1098 systemd-resolve  13u   IPv4  30039       0t0  TCP localhost:domain (LISTEN)
avahi-dae 1173           avahi  12u   IPv4  34421       0t0  UDP *:mdns 
avahi-dae 1173           avahi  13u   IPv6  34422       0t0  UDP *:mdns 
avahi-dae 1173           avahi  14u   IPv4  34423       0t0  UDP *:55636 
avahi-dae 1173           avahi  15u   IPv6  34424       0t0  UDP *:58178 
cupsd     1175            root   6u   IPv6  34242       0t0  TCP ip6-localhost:ipp (LISTEN)
cupsd     1175            root   7u   IPv4  34243       0t0  TCP localhost:ipp (LISTEN)
NetworkMa 1177            root  22u   IPv4  37029       0t0  UDP layla:bootpc->_gateway:bootps 
cups-brow 1309            root   7u   IPv4  36538       0t0  UDP *:631 
brave     4783            alex  40u   IPv4  98557       0t0  TCP layla:36598->104.16.121.96:https (ESTABLISHED)
brave     4783            alex  47u   IPv4  97067       0t0  TCP layla:36602->104.16.121.96:https (ESTABLISHED)

Эта команда также достаточно удобна для отслеживания состояния TCP-соединений.