Как проверить статус открытия файлов в linux — команда lsof

Linux

предисловие

Все мы знаем, что под linux «все является файлом», поэтому иногда очень важно проверить статус открытия файлов, и вот команда, которая может нам очень хорошо помочь в этом вопросе — это lsof.

Какие файлы есть под линуксом

Прежде чем представить команду lsof, давайте кратко поговорим об основных файлах в Linux:

  • обычный файл
  • содержание
  • символическая ссылка
  • блочный файл устройства
  • символьно-ориентированный файл устройства
  • Каналы и именованные каналы
  • разъем

Вышеупомянутые типы файлов подробно не описаны.

Введение в практическое использование команды lsof

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

Просмотреть все открытые в данный момент файлы

Как правило, прямой ввод команды lsof приводит к такому большому количеству результатов, что поиск нужной информации может оказаться затруднительным. Однако это должно объяснить, какая информация содержится в записи.

$ lsof(这里选取一条记录显示)
COMMAND   PID                      USER   FD             TYPE        DEVICE SIZE/OFF   NODE   NAME
vi        27940                    hyb    7u      REG               8,15     16384     137573 /home/hyb/.1.txt.swp

Результаты, отображаемые lsof, представлены слева направо: имя программы, которая открыла файл, идентификатор процесса, пользователь, дескриптор файла, тип файла, устройство, размер, номер iNode и имя файла.

Давайте сосредоточимся на столбцах, которые мы знаем на данный момент. Эта запись указывает, что программа vi с идентификатором процесса 27940 открыла обычный файл (обычный файл REG).1.txt.swap в каталоге /home/hyb со значением описания файла 7 и находится в состоянии чтения-записи. , Текущий размер 16384 байт.

Список удаленных файлов, но занимающих место

В производственной среде мы можем использовать команду df, чтобы увидеть, что место на диске заполнено, но на самом деле трудно найти файл с полным пространством.Это часто происходит из-за удаления большого файла, но он был удален Определенный Процесс открыт, и его следы не могут быть обнаружены обычными средствами, чаще всего в файлах журналов. Мы можем найти такие файлы через lsof:

$ lsof |grep deleted
Xorg      1131 root  125u      REG                0,5        4      61026 /memfd:xshmfence (deleted)
Xorg      1131 root  126u      REG                0,5        4      62913 /memfd:xshmfence (deleted)
Xorg      1131 root  129u      REG                0,5        4      74609 /memfd:xshmfence (deleted)

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

Восстановить открытые, но удаленные файлы

Раньше мы могли найти файл, который был удален, но все еще открывался, на самом деле файл не исчез, если он был случайно удален, у нас еще есть средства для его восстановления. Возьмем в качестве примера файл /var/log/syslog, давайте сначала удалим его (пользователь root):

$ rm /var/log/syslog

Затем используйте lsof, чтобы узнать, в каком процессе открыт файл:

$ lsof |grep syslog
rs:main    993 1119           syslog    5w      REG               8,10     78419     528470 /var/log/syslog (deleted)

Можно обнаружить, что файл открыл процесс с идентификатором процесса 993. Мы знаем, что у каждого процесса есть запись файлового дескриптора, открытая в /proc:

$ ls -l /proc/993/fd
lr-x------ 1 root   root   64 3月   5 18:30 0 -> /dev/null
l-wx------ 1 root   root   64 3月   5 18:30 1 -> /dev/null
l-wx------ 1 root   root   64 3月   5 18:30 2 -> /dev/null
lrwx------ 1 root   root   64 3月   5 18:30 3 -> socket:[15032]
lr-x------ 1 root   root   64 3月   5 18:30 4 -> /proc/kmsg
l-wx------ 1 root   root   64 3月   5 18:30 5 -> /var/log/syslog (deleted)
l-wx------ 1 root   root   64 3月   5 18:30 6 -> /var/log/auth.log

Здесь находим удаленный файл syslog, дескриптор файла 5, перенаправляем его наружу:

$ cat /proc/993/fd/5 > syslog
$ ls -al /var/log/syslog
-rw-r--r-- 1 root root 78493 3月   5 19:22 /var/log/syslog

Таким образом мы восстанавливаем файл системного журнала.

Проверить, какими процессами открыт текущий файл

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

Linux проще, просто используйте команду lsof, например, чтобы увидеть, какие программы в данный момент открывают hello.c:

$ lsof hello.c
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
tail    28731  hyb    3r   REG   8,15      228 138441 hello.c

Но мы обнаружим, что файл hello.c, открытый с помощью vi, не найден, потому что vi открывает временную копию. Найдем по-другому:

$ lsof |grep hello.c
tail      28906                    hyb    3r      REG               8,15       228     138441 /home/hyb/workspaces/c/hello.c
vi        28933                    hyb    9u      REG               8,15     12288     137573 /home/hyb/workspaces/c/.hello.c.swp

Таким образом, мы обнаружили две программы, связанные с файлом hello.c.

Роль grep здесь состоит в том, чтобы перечислить только подходящие результаты из всех результатов.

Проверить, открыт ли файл каталога

$ lsof +D ./

Посмотреть, какие файлы открыты текущим процессом

Как использовать: lsof -c имя процесса Обычно он используется для решения проблем с позиционированием программ, например, чтобы увидеть, какие библиотеки используются текущим процессом, какие файлы открыты и т. д. Предположим, у вас есть программа hello, которая печатает символы в цикле:

$ lsof -c hello
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
hello   29190  hyb  cwd    DIR   8,15     4096 134538 /home/hyb/workspaces/c
hello   29190  hyb  rtd    DIR   8,10     4096      2 /
hello   29190  hyb  txt    REG   8,15     9816 138314 /home/hyb/workspaces/c/hello
hello   29190  hyb  mem    REG   8,10  1868984 939763 /lib/x86_64-linux-gnu/libc-2.23.so
hello   29190  hyb  mem    REG   8,10   162632 926913 /lib/x86_64-linux-gnu/ld-2.23.so
hello   29190  hyb    0u   CHR 136,20      0t0     23 /dev/pts/20
hello   29190  hyb    1u   CHR 136,20      0t0     23 /dev/pts/20
hello   29190  hyb    2u   CHR 136,20      0t0     23 /dev/pts/20

Мы видим, что по крайней мере он использует /lib/x86_64-linux-gnu/libc-2.23.so и файл hello.

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

$ lsof -p 29190
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
hello   29190  hyb  cwd    DIR   8,15     4096 134538 /home/hyb/workspaces/c
hello   29190  hyb  rtd    DIR   8,10     4096      2 /
hello   29190  hyb  txt    REG   8,15     9816 138314 /home/hyb/workspaces/c/hello
hello   29190  hyb  mem    REG   8,10  1868984 939763 /lib/x86_64-linux-gnu/libc-2.23.so
hello   29190  hyb  mem    REG   8,10   162632 926913 /lib/x86_64-linux-gnu/ld-2.23.so
hello   29190  hyb    0u   CHR 136,20      0t0     23 /dev/pts/20
hello   29190  hyb    1u   CHR 136,20      0t0     23 /dev/pts/20
hello   29190  hyb    2u   CHR 136,20      0t0     23 /dev/pts/20

Конечно, здесь есть и другой способ: использовать файловую систему proc, чтобы сначала найти идентификатор процесса приветствия. :

$ ps -ef|grep hello
hyb      29190 27929  0 21:14 pts/20   00:00:00 ./hello 2
hyb      29296 28848  0 21:18 pts/22   00:00:00 grep --color=auto hello

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

$ ls -l /proc/29190/fd
lrwx------ 1 hyb hyb 64 3月   2 21:14 0 -> /dev/pts/20
lrwx------ 1 hyb hyb 64 3月   2 21:14 1 -> /dev/pts/20
lrwx------ 1 hyb hyb 64 3月   2 21:14 2 -> /dev/pts/20

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

Публичный аккаунт WeChat [Programming Pearl]: сосредоточьтесь, помимо прочего, на том, чтобы поделиться основами компьютерного программирования, Linux, языком C, C++, структурами данных и алгоритмами, инструментами, ресурсами и другими [оригинальными] техническими статьями, связанными с программированием.

Оригинальный адрес:Ууху.Yanbinghu.com/2019/03/05/…

Проверить занятость порта

При использовании базы данных или включении веб-службы вы всегда можете столкнуться с проблемами занятости порта, так как же проверить, занят ли порт?

$ lsof -i :6379
COMMAND     PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 29389  hyb    6u  IPv6 534612      0t0  TCP *:6379 (LISTEN)
redis-ser 29389  hyb    7u  IPv4 534613      0t0  TCP *:6379 (LISTEN)

Здесь видно, что процесс redis-ser занимает порт 6379.

Просмотреть все соединения TCP/UDP

$ lsof -i tcp
ava       2534  hyb    6u  IPv6  31275      0t0  TCP localhost:9614 (LISTEN)
java       2534  hyb   22u  IPv6  96922      0t0  TCP localhost:9614->localhost:39004 (ESTABLISHED)
java       2534  hyb   23u  IPv6 249588      0t0  TCP localhost:9614->localhost:45460 (ESTABLISHED)

Конечно, мы также можем использовать команду netstat.

$ netstat -anp|grep 6379

За параметром -i здесь может следовать множество условий:

  • -i 4    #ipv4адрес
  • -i 6    #ipv6адрес
  • -i tcp  #tcp соединение
  • -i :3306  #порт
  • -i @ip  #ip-адрес

Поэтому, когда вам нужно просмотреть соединение, установленное с ip-адресом, вы можете использовать следующие методы:

$ lsof -i@127.0.0.1

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

Linux — многопользовательская операционная система, как узнать, какие файлы открыты другими обычными пользователями? Можно использовать параметр -u

$ lsof -u hyb
(内容太多,省略)

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

По сути, он аналогичен предыдущему способу, за исключением того, что перед идентификатором процесса или именем пользователя добавляется ^, например:

lsof -p ^1     #列出除进程id为1的进程以外打开的文件
lsof -u ^root  #列出除root用户以外打开的文件

Суммировать

Приведенное выше введение основано на одном условии, но на самом деле можно комбинировать несколько условий, например, перечисление файлов сокетов tcp, открытых процессом с идентификатором процесса 1:

lsof -p 1 -i tcp

Есть много параметров lsof, которые можно просмотреть с помощью команды man, но для нас достаточно знать эти практические параметры.

Публичный аккаунт WeChat [Programming Pearl]: сосредоточьтесь, помимо прочего, на том, чтобы поделиться основами компьютерного программирования, Linux, языком C, C++, структурами данных и алгоритмами, инструментами, ресурсами и другими [оригинальными] техническими статьями, связанными с программированием.