lsof
Install
sudo apt install lsof
Options
-u
– выводит список файлов, открытых конкретным пользователем,-U
– позволяет вывести все файлы сокетов домена Unix,-c
– позволяет вывести сведения о файлах, которые держат открытыми процессы, выполняющие команды, имена которых начинаются с заданных символов.+d
– позволяет выяснить, какие папки и файлы открыты в некоей директории (но не в её поддиректориях),-d
– опция позволяет задать список дескрипторов файлов, разделённых запятой, которые надо включить в вывод или исключить из него,-p
– позволяет вывести все файлы, открытые процессом с указанным при вызове команды PID,-P
– подавляет, для сетевых файлов, преобразование номеров портов в имена портов. Её полезно использовать в тех случаях, когда разрешение имён портов работает неправильно.-i
– позволяет вывести сведения о файлах, интернет-адреса которых соответствуют заданному адресу. Если при вызове команды не задавать адреса, эта опция позволяет вывести сведения обо всех интернет-сокетах и сетевых файлах.-t
– подавляет вывод всей информации за исключением ID процессов. Её часто используют, если нужно перенаправить список PID какой-нибудь другой команде, в основном –kill-9
SYNOPSIS
lsof [ -?abChKlnNOPRtUvVX ] [ -A A ] [ -c c ] [ +c c ] [ +|-d d ] [+|-D D ] [ +|-e s ] [ +|-f [cfgGn] ] [ -F [f] ] [ -g [s] ] [ -i [i] ] [-k k ] [ +|-L [l] ] [ +|-m m ] [ +|-M ] [ -o [o] ] [ -p s ] [ +|-r[t[m<fmt>]] ] [ -s [p:s] ] [ -S [t] ] [ -T [t] ] [ -u s ] [ +|-w ] [ -x[fl] ] [ -z [z] ] [ -Z [Z] ] [ -- ] [names]
Если просто запустить lsof, получим вывод, где можно увидеть заголовок, такой как команда, Pid, User, FD и т. д. Большинство столбцов и их значений говорят сами за себя. ИЗа исключением FD. FD относится к файловому дескриптору и содержит такие значения, как:
FD
cwd
– текущий рабочий каталог;mem
– файл, загруженный в память, чаще всего — библиотека;mxx
— hex memory-mapped type;mmap
– memory-mapped device;pd
– родительский каталог;rtd
– корневой каталог;тхт
– текст программы (код и данные);
Кроме того, в столбцах FD такие номера (такие, как 1u), которые, фактическим являются дескриптором файла, а за ним следует один из флагов u, r, w как режим доступа:
r
– доступа для чтения;w
– доступа для записи;u
– чтения и записи;пробел
– режим доступа неизвестен и файл не блокирован;-
– режим доступа неизвестен, но на файл установлена блокировка.
TYPE – файлов и их идентификация:
DIR
– директория;REG
– обычный файл;CHR
– файл символьного устройства;FIFO
– First In First Out;LINK
– Симлинк;INET
– Internet-сокет;UNIX
– доменный сокет UNIX.
Examples
Следующий пример показывает, как можно узнать, сколько файлов держит открытыми пользователь nevvad:
lsof -u nevvad | wc -l 179
Обычно, если перед параметром некоей опции ставят знак ^
(caret), который означает отрицание, это приводит к исключению файлов, соответствующих данному параметру, из вывода программы. Вот, например, как можно узнать количество файлов на компьютере, которые открыты всеми пользователями за исключением nevvad.
lsof -u^nevvad | wc -l 3949
Вот какая команда позволит увидеть первые 15 файлов, открытых всеми процессами mariadbd, выполняющимися на компьютере
lsof -cmariadbd | head -15
Смотрим, какие каталоги и файлы открыты в некоей директории (но не в её поддиректориях).
lsof +d /usr/bin/ | head -5
К примеру выше, можно привести пример из жизни, пытаемся отмонтировать например CD-ROM, но получаем ошибку – Device is busy. Это означает, что какой-то процесс открыл файл, расположенный на этом устройстве. Смотрим:
lsof +d /mnt/cdrom COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME mc 1547 rok cwd DIR 11,0 2048 53248 /mnt/cdrom bash 1556 rok cwd DIR 11,0 2048 53248 /mnt/cdrom
Как видим, сразу становится ясно, что дисковод используется пользователем rok, причем, видимо, какой-то подкаталог каталога /mnt/cdrom
открыт в одной из панелей файлового менеджера Mifnight Commander (mc).
Вывод информации обо всех файлах, открытых процессом, скажем, с PID 1 в Ubuntu 22.04
lsof -p 1 | head -10 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root cwd DIR 253,0 4096 2 / systemd 1 root rtd DIR 253,0 4096 2 / systemd 1 root txt REG 253,0 1849992 13989 /usr/lib/systemd/systemd systemd 1 root mem REG 253,0 149760 1447 /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.32.1 systemd 1 root mem REG 253,0 4447536 936 /usr/lib/x86_64-linux-gnu/libcrypto.so.3 systemd 1 root mem REG 253,0 27072 746 /usr/lib/x86_64-linux-gnu/libcap-ng.so.0.0.0 systemd 1 root mem REG 253,0 613064 1434 /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.10.4 systemd 1 root mem REG 253,0 170456 10218 /usr/lib/x86_64-linux-gnu/liblzma.so.5.2.5 systemd 1 root mem REG 253,0 841808 8018 /usr/lib/x86_64-linux-gnu/libzstd.so.1.4.8
Смотрим на TCP-соединения, открытые клиентом Dropbox.
lsof -i -a -u $USER | grep dropbox
Находим процессы, которые прослушивают определенный диапазон портов
lsof -i TCP:1-100
Завершаем указанные процессы:
kill -9 $(lsof -t -i:8080)
Либо сохраняем PID процессов в лог, для дальнейшей экзекуции:
lsof -t /var/log/dummy_svc.log
Поищем, куда пишется определенный процесс, пусть это будут логи squid:
lsof | grep squid | grep log squid 18671 squid 5u REG 253,0 3073 784030 /var/log/squid/cache.log squid 18671 squid 8w REG 253,0 4041 784031 /var/log/squid/store.log
Так же очень полезной является опция +L1
. +L1
показывает файлы, которые были удалены, но все ещё используются какой-то программой, чаще всего логирование. Если сталкиваетесь с ситуацией, что место постоянно заканчивается, а найти файлы, которые его заполняют не получается, тогда просто нужно будет убить процесс, который использует этот файл и место сразу же освободится:
lsof -a +L1 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME mariadbd 3037 mysql 6u REG 253,0 0 0 17110 /tmp/#17110 (deleted) mariadbd 3037 mysql 7u REG 253,0 0 0 17111 /tmp/#17111 (deleted) mariadbd 3037 mysql 8u REG 253,0 0 0 17309 /tmp/#17309 (deleted) mariadbd 3037 mysql 11u REG 253,0 0 0 17310 /tmp/#17310 (deleted) # Ну или так lsof | grep deleted
Комбинирование опций
Обычно lsof объединяет результаты использования нескольких опций, следуя принципу логического ИЛИ. Если задать опцию -a
, результаты будут объединены по правилам логического И.
Конечно, есть несколько исключений из этого правила, тут, как обычно, рекомендовано взглянуть на документацию, но если в двух словах, то работает это так:
Обычно заданные опции списка объединяются по принципу логического ИЛИ, то есть, если указать опцию -i
без указания адреса, и опцию -u foo
, будет выведен список всех сетевых файлов или файлов, принадлежащих процессам, владельцем которых является пользователь «foo». Из этого правила есть несколько исключений:
- Имя пользователя или ID пользователя (UID) со знаком
^
(отрицание), заданное с опцией-u
; - Идентификатор процесса (PID) со знаком
^
(отрицание), заданный с опцией-p
; - Группа процессов (PGID) со знаком
^
(отрицание), заданная с опцией-g
; - Имя команды со знаком
^
(отрицание), заданное с опцией-c
; - Имена состояний протоколов TCP или UDP, заданные с опцией
-s [p:s]
.
К примеру:
lsof -a -U -u nevvad
Выдаст список только сокетов UNIX, принадлежащих процессам, владельцем которых является пользователь nevvad. Обратите внимание на то, что опция -a
стоит не между объединяемыми ею другими опциями. Впрочем, ее можно ставить где угодно, все равно все перечисленные в командной строке опции будут работать по принципу «логическое И».