Показать статистику
0 голосов
от (620 баллов)
Хочу удалить один старый лог-файл, но хотелось бы отследить что же именно туда пишет. Очень редко (раз в несколько часов) какой то сервис добавляет туда записи. Как вычислить этот сервис?
1.8тыс. просмотров 1 ответов

1 Ответ

0 голосов
от (940 баллов)

Для того, чтобы выяснить какой процесс обращается к файлу или каталогу в GNU/Linux используется утилита командной строки lsof (LiSt of Open Files).

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

Для начала стоит рассмотреть: какую информацию предоставляет нам команда:

COMMAND     PID   TID             USER   FD      TYPE             DEVICE SIZE/OFF       NODE NAME

sh        23252     user    4u   CHR        5,0               70758 /dev/tty
sh        23252     user    6u   CHR      136,3                   5 /dev/pts/3
sh        23252     user    8w  FIFO        0,5              840800 pipe
sh        23253     user  cwd    DIR        3,3     4096     160487 /usr/share/man
sh        23253     user  rtd    DIR        3,3     4096          2 /
sh        23253     user  txt    REG        3,3   626028     160664 /bin/bash

В первой колонке содержится команда запуска процесса или имя процесса, затем PID (идентификатор процесса), имя пользователя, с правами которого запущен процесс,  FD (файловый дескриптор), тип файла, устройство, размер файла, номер индексного дескриптора и имя файла.

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

  1. COMMAND - имя команды, с помошью которой был запущен процесс. Так же можно считать это именем процесса, но стоит учесть, что значение это вполне может быть не уникальным. К тому же имя процесса - это совсем не обязательно имя исполняемого файла в системе. Например, процесс с именем sh в разных системах может скрывать за собой различные командные оболочки. В нашем случае - это /bin/bash.
  2. PID - Этот столбец однозначно определяет процесс. Именно по этому идентификатору можно различить одноименные процессы в списке.
  3. TID - Идентификатор потока. Если процесс не создает дочерних потоков - столбец будет пустым.
  4. USER - Имя пользователя, с правами которого запущен процесс.

  5. FD - Файловый дескриптор.

    Файловый дескриптор сопровождается следующими символами, обозначающими тип доступа: r/w/u/ /- - чтение/запись/запись и чтение/не известно, файл не блокирован/не известно, файл блокирован. Так же столбец FD содержит информацию о типе файлового фескриптора (описаны основные):

    • cwd  - рабочий каталог;

    • err - Ошибка получения информации FD;

    • ltx - текст разделяемой библиотеки;

    • Mxx - hex-ссылка в отображаемую память;

    • mem - Файл в памяти;

    • mmap - Устройство, отображенное в памяти;

    • pd - Родительский каталог;

    • rtd - Корневой каталог;

    • txt - текст программы (код и данные).

  6. TYPE - В этом столбце указывается тип файла (описаны основные):
    • REG - обычный файл;
    • DIR - каталог;
    • BLK - блочное устройство;
    • CHR - символьное устройство;
    • LINK - символическая ссылка;
    • INET – Internet-сокет;
    • UNIX – доменный сокет UNIX.
  7. DEVICE - содержит номера устройств, для символьного или блочного устройства, обычного файла или каталога.
  8. SIZE - размер файла или каталога.
  9. NODE - Номер индексного дескриптора.
  10. NAME - Имя файла.

Именно в столбце NAME можно увидеть - какой файл отвечает за выполнение команды в случае исполняемого файла.

В зависимости от версии и настроек системы, объем выводимых сведений может сильно отличаться.

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

Например, можно использовать следующую команду:

lsof -F pcn /log/sample.log

Здесь:

  • - F pcn - Ограничиваем вывод столбцами PID,COMMAND и NAME. Другая информация нам не интересна;
  • /log/sample.log - имя исследуемого файла.

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

На этот случай есть еще один параметр: -/+r [t[m<fmt>]].

Что он делает: При использовании этого параметра мы заставляем lsof перейти в режим "repeat". В этом режиме команда начинает "наблюдать" за файлом и сообщать о каждом к нему обращении.

Применять параметр можно несколькими способами:

  • -r - выполнять команду бесконечно. Прерывание по Ctrl+C.
  • +r - lsof ждет закрытия уже открытого файла и завершается.
  • t - указывает период между "снимками" в секундах. По-умолчанию - 15
  • m - указывает формат времени (см. strftime)

В нашем случае команда, наблюдающая за интересующим нас файлом будет выглядеть вот так:

lsof - F pcn -r1m%H:%M:%S /log/sample.log

Это значит, что lsof каждую секунду будет проверять - не открыл ли кто-нибудь интересующий нас файл и выводить информацию о процессе. Следует заметить - файл должен существовать на момент запуска и у пользователя должны быть права на чтение.

Между прочим, у комманды lsof имеются и более любопытные применения. Например, наблюдение за сетевыми подключениями:

Просмотреть - какие порты открыты в системе и какой процесс их использует (слушает):
/usr/sbin/lsof -i 

Более подробную информацию можно получить с помощью команды man lsof.
Для lsof разработана графическая оболочка, называемая GLSOF. Ее можно получить с сайта http://glsof.sourceforge.net/.
Автор программы lsof: Victor A. Abell, его домашняя страничка: http://people.freebsd.org/~abe/.

...