Использование утилиты lsof в примерах

Автор: | 17/08/2013

terminalИмя утилиты LSOF является аббревиатурой от List Of Opened Files, и предназначена она, как следует из названия, для отображения открытых файлов различными процессами и/или пользователями.

Если утилиты в системе нет – установим её.

Для FreeBSD выполняем:

# cd /usr/ports/sysutils/lsof && make BATCH=yes install clean

Хотя у FreeBSD есть родная аналогичные утилиты fstat и sockstat.

Для CentOS:

# yum -y install lsof

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

# lsof | less

COMMAND    PID    USER   FD      TYPE     DEVICE SIZE/OFF       NODE NAME
init         1    root  cwd       DIR      253,0     4096          2 /
init         1    root  rtd       DIR      253,0     4096          2 /
init         1    root  txt       REG      253,0   149284         38 /sbin/init
init         1    root  mem       REG      253,0   284780     262198 /lib/libdbus-1.so.3.4.0
init         1    root  mem       REG      253,0  1902708     262110 /lib/libc-2.12.so

Информация предоставляется в виде колонок, в которых отображается информация:

COMMAND   – имя процесса;
PID – его Process ID;
USER – имя пользователя, запустившего процесс;
FD – номер файлового дескриптора, либо обозначение типа:

  • cwd – текущий рабочий каталог;
  • ltx – текст разделяемой библиотеки;
  • mem – файл, загруженный в память (memory-mapped file), чаще всего – библиотека,
  • mmap – memory-mapped device;
  • pd – родительский каталог;
  • rtd – корневой каталог;
  • txt – текст программы (код и данные);

Номер файлового дескриптора дополняется символом, указывающим режим, в котором файл был открыт:

  • r – файл открыт для чтения;
  • w – файл открыт для записи;
  • u – файл открыт для чтения и для записи;
  • пробел – режим доступа неизвестен и файл не блокирован;
  • ‘-’ – режим доступа неизвестен, но на файл установлена блокировка.

В последнем случае за дефисом следует еще один символ, определяющий тип блокировки.

TYPE – тип открытого файла, обозначающиеся: REG – обычный файл, DIR – каталог, BLK – файл блочного устройства, CHR – файл символьного устройства, LINK – файл символической ссылки, INET – Internet-сокет, UNIX – доменный сокет UNIX;
DEVICE – устройство, на котором открыт данный файл;
SIZE/OFF – размер файла в байтах;
NODE – номер индексного дескриптора (inode);
NAME – собственно, имя самого файла и путь к нему.

Приведённое описание сравнительно краткое, больше информации можно найти в man lsof или, например, тут>>>.

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

Отобразить список процессов/пользователей, использующих в данный момент файл /usr/sbin/sshd:

# lsof /usr/sbin/sshd
COMMAND  PID    USER  FD   TYPE DEVICE SIZE/OFF   NODE NAME
sshd    1088    root txt    REG  253,0   524144 657883 /usr/sbin/sshd
sshd    1201    root txt    REG  253,0   524144 657883 /usr/sbin/sshd
sshd    1205 setevoy txt    REG  253,0   524144 657883 /usr/sbin/sshd

Можно указать несколько файлов и/или каталогов, разделив их пробелом:

# lsof /usr/sbin/sshd /home/setevoy
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
sshd    1088    root  txt    REG  253,0   524144 657883 /usr/sbin/sshd
bash    1206 setevoy  cwd    DIR  253,0     4096    213 /home/setevoy

Отобразить список процессов и пользователей, использующих каталог /home/setevoy/:

# lsof +d /home/setevoy/
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    1206 setevoy  cwd    DIR  253,0     4096  213 /home/setevoy
su      1223    root  cwd    DIR  253,0     4096  213 /home/setevoy
bash    1227    root  cwd    DIR  253,0     4096  213 /home/setevoy
lsof    1253    root  cwd    DIR  253,0     4096  213 /home/setevoy
lsof    1254    root  cwd    DIR  253,0     4096  213 /home/setevoy

Что бы отобразить и все подкаталоги – используйте ключ +D:

# lsof +D /home/setevoy/
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
su      1223    root  cwd    DIR  253,0     4096  213 /home/setevoy
bash    1227    root  cwd    DIR  253,0     4096  213 /home/setevoy
screen  1258    root  cwd    DIR  253,0     4096  213 /home/setevoy
bash    1260    root  cwd    DIR  253,0     4096  132 /home/setevoy/dir1
bash    1267    root  cwd    DIR  253,0     4096  132 /home/setevoy/dir1
lsof    1281    root  cwd    DIR  253,0     4096  213 /home/setevoy
lsof    1282    root  cwd    DIR  253,0     4096  213 /home/setevoy

Отобразить файлы, открытые процессом screen:

# lsof -c screen
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
screen  1258 root  cwd    DIR  253,0     4096    213 /home/setevoy
screen  1258 root  rtd    DIR  253,0     4096      2 /
screen  1258 root  txt    REG  253,0   371220 658057 /usr/bin/screen
screen  1258 root  mem    REG  253,0    38376 262114 /lib/libcrypt-2.12.so

Тут надо отметить, что опция -c учитывает заданное имя “по маске”. Т.е. результат будет включать в себя процессы, в имени которых содержится строка “screen“.

Как и выводом информации о файлах, можно использовать несколько значений:

# lsof -c screen -c vi
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
screen  1258 root  cwd    DIR  253,0     4096    213 /home/setevoy
screen  1258 root  rtd    DIR  253,0     4096      2 /
...
vi      1286 root  cwd    DIR  253,0     4096    213 /home/setevoy
vi      1286 root  rtd    DIR  253,0     4096      2 /
vi      1286 root  txt    REG  253,0   715044 784795 /bin/vi

Для более точного указания процесса – можно указать PID процесса:

# lsof -p 1205
COMMAND  PID    USER   FD   TYPE     DEVICE SIZE/OFF   NODE NAME
sshd    1205 setevoy  cwd    DIR      253,0     4096      2 /
sshd    1205 setevoy  rtd    DIR      253,0     4096      2 /
sshd    1205 setevoy  txt    REG      253,0   524144 657883 /usr/sbin/sshd

Можно задать несколько PID, разделив их запятыми (без пробелов):

# lsof -p 1205,1259

Наиболее полезная возможность – отобразить файлы, открытые определённым пользователем:

# lsof -u setevoy
COMMAND  PID    USER   FD   TYPE     DEVICE SIZE/OFF   NODE NAME
sshd    1205 setevoy  cwd    DIR      253,0     4096      2 /
sshd    1205 setevoy  rtd    DIR      253,0     4096      2 /
sshd    1205 setevoy  txt    REG      253,0   524144 657883 /usr/sbin/sshd
sshd    1205 setevoy  mem    REG      253,0   120780 265084 /lib/libselinux.so.1

Что бы вывести всё, кроме пользователя setevoy – используйте комбинацию ^:

# lsof -u ^setevoy

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

Тут так же можно использовать несколько имён и/или UID-ов, разделённых запятой:

# lsof -u setevoy,0

Где 0 – это UID пользователя root.

Кроме того, lsof может отобразить активные сетевые включения, аналогично утилите netstat (подробнее о ней в статье netstat: примеры использования, опции), для этого выполняем:

# lsof -i
COMMAND   PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
dhclient  989    root    5u  IPv4  10367      0t0  UDP *:bootpc
sshd     1088    root    3u  IPv4  10634      0t0  TCP *:ssh (LISTEN)
sshd     1088    root    4u  IPv6  10636      0t0  TCP *:ssh (LISTEN)
master   1164    root   12u  IPv4  10836      0t0  TCP localhost:smtp (LISTEN)
master   1164    root   13u  IPv6  10838      0t0  TCP localhost:smtp (LISTEN)

sshd     1201    root    3r  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)
sshd     1205 setevoy    3u  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)

В кололнке NAME так же указывается состояние соединения – LISTEN (готов к приёму соединения), ESTABLISHED (установлено).

Можно задать более точные параметры для вывода информации в формате [46][protocol][@hostname|hostaddr][:service|port].

4 и/или 6 – версия протокола IP (IPV4/IPV6);
protocol – либо TCP, либо UDP (либо ничего);
hostname – имя хоста;
hostaddr – числовой адрес;
service – имя интересующего сервиса, например – smtp, или список таких сервисов;
port – номер порта или список таких номеров.

Например, отобразить сервисы, прослушивающие порт 22 и/или уже установленные соединения на этом порту:

# lsof -i :22
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1088    root    3u  IPv4  10634      0t0  TCP *:ssh (LISTEN)
sshd    1088    root    4u  IPv6  10636      0t0  TCP *:ssh (LISTEN)
sshd    1201    root    3r  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)
sshd    1205 setevoy    3u  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)

Либо – по имени сервиса:

# lsof -i :ssh
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1088    root    3u  IPv4  10634      0t0  TCP *:ssh (LISTEN)
sshd    1088    root    4u  IPv6  10636      0t0  TCP *:ssh (LISTEN)
sshd    1201    root    3r  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)
sshd    1205 setevoy    3u  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)

Отобразить активные подключения с адреса 192.168.1.100:

# lsof -i @192.168.1.100
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1201    root    3r  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)
sshd    1205 setevoy    3u  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)

Либо – скомбинировать все эти ключи:

# lsof -i [email protected]:58132
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1201    root    3r  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)
sshd    1205 setevoy    3u  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)

Можно отобразить, например, только те процессы и файлы, у которых в колонке FD указан тип “mem“:

# lsof -d mem

Полезная опция -t – вывести только PID-ы процессов. Например – отобразить активные PID пользователя setevoy:

# lsof -t -u setevoy
1205
1206

Эту комбинацию удобно использовать вместе с другими командами. Например – “убить” все сетевые процессы:

# kill -9 `lsof -t -i`

Или – убить все сетевые процессы пользователя setevoy:

# kill -9 `lsof -t -u setevoy -i -a`

Тут необходимо остановиться подробнее на опции -a.

По-умолчанию, при использовании нескольких опций lsof выведет информацию о всех попадающих под эти опции процессах, т.е. используется логическое ИЛИ.

Например:

# lsof -p 1205 -u setevoy
COMMAND  PID    USER   FD   TYPE     DEVICE SIZE/OFF   NODE NAME
sshd    1205 setevoy  cwd    DIR      253,0     4096      2 /
sshd    1205 setevoy  rtd    DIR      253,0     4096      2 /
...
bash    1206 setevoy  cwd    DIR      253,0     4096    213 /home/setevoy
bash    1206 setevoy  rtd    DIR      253,0     4096      2 /

В такой комбинации будет отображена информация о файлах, открытых процессом с PID 1205, а так же – процессы пользователя setevoy.

Если же необходимо указать четкое значение “опция 1 И опция 2” – используется ключ -a.

Например, вывести информацию о файле /usr/sbin/sshd, который открыт пользователем setevoy:

# lsof -u setevoy -a /usr/sbin/sshd
COMMAND  PID    USER  FD   TYPE DEVICE SIZE/OFF   NODE NAME
sshd    1205 setevoy txt    REG  253,0   524144 657883 /usr/sbin/sshd

Ещё одна полезгная опция утилиты lsof – ключ -r, который выполняет запрос циклически, через заданный в секундах промежуток времени.

Например – отобразить все активные сетевые соединения пользователя setevoy и обновлять информацию каждые 10 секунд (обратите внимание, что тут тоже используется ключ -a для уточнения отображаемой информации:

# lsof -r 1 -u setevoy -i -a
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
...=======
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1205 setevoy    3u  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)
=======
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
sshd    1205 setevoy    3u  IPv4  11268      0t0  TCP 192.168.1.108:ssh->192.168.1.100:58132 (ESTABLISHED)
=======
...