Как получить имя файла вместе с абсолютным путем к файлу, всякий раз, когда новый файл создается с использованием inode в Linux?

Я проводил некоторые эксперименты с моей ОС Linux (CentOS) и хочу отслеживать все журналы инструментов, созданные в одной среде, инструмент генерирует соответствующие журналы (.log extn) для отслеживания этих изменений. Я написал Perl Watcher, который фактически контролирует каталог что я установил, и когда новый файл будет создан, он будет отображаться на выходе, но это потребляет много памяти и использования процессора, так как я установил 2sec в качестве периода ожидания.

Мой вопрос "Есть ли лучший способ сделать это?" Я думал об использовании таблицы inode для отслеживания всех изменений в системе. это может решить мою проблему? и если да, то, пожалуйста, дайте нам знать решение в том же направлении?

1 ответ

Решение

Кажется, вы хотите отслеживать каталог на предмет изменений. Это сложная работа, но для которой есть хорошие модули. Вероятно, самый простой из них - Linux::Inotify2

Этот модуль реализует интерфейс к Linux 2.6.13 и более поздним версиям системы уведомлений об изменении файлов / каталогов Inotify.

Это похоже на то, что вы хотели.

Любой такой монитор требует дополнительной обработки событий. В этом примере используется AnyEvent.

use warnings;
use strict;
use feature 'say';

use AnyEvent;
use Linux::Inotify2;

my $dir = 'dir_to_watch';

my $inotify = Linux::Inotify2->new  or die "Can't create inotify object: $!";

$inotify->watch( $dir, IN_MODIFY | IN_CREATE, sub {
    my $e = shift;
    my $name = $e->fullname;
    say "$name modified" if $e->IN_MODIFY;    # Both show the new file
    say "$name created"  if $e->IN_CREATE;    # but see comments below
});

my $inotify_w = AnyEvent->io (
    fh => $inotify->fileno, poll => 'r', cb => sub { $inotify->poll }
);

1 while $inotify->poll;

Если вам нужны только новые файлы, вам нужна только одна константа выше. Для обоих типов событий $name имеет имя нового файла. От man inotify в моей системе

... name поле в возвращаемом inotify_event Структура идентифицирует имя файла в каталоге.

inotify_event структура соответственно представлена Linux::Inotify2::Watcher объект.

С помощью IN_CREATE кажется очевидным решением для вашей цели. Я проверил, создав два файла, с двумя перенаправленными echo команды, разделенные точкой с запятой в той же командной строке, а также touch-ing файл. Записанные файлы обнаруживаются как отдельные события, как и touchфайл.

С помощью IN_MODIFY может также работать, так как он контролирует (в $dir)

... любой объект файловой системы в наблюдаемом объекте (всегда каталог), то есть файлы, каталоги, символические ссылки, узлы устройств и т. д....

Что касается тестов, оба файла написаны echo как указано выше, сообщается, как отдельные события. Но touchфайл не сообщается, так как данные не изменились (файл не был записан).

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

Мы можем думать о состоянии гонки, поскольку при выполнении кода могут появиться другие файлы. Но модуль гораздо лучше, и он сообщает о новых изменениях после завершения обработчика. Я тестировал, создавая файлы, пока этот код работает (и спит), и о них сообщается.

Некоторые другие известные платформы для событийно-управляемого программирования - это POE и IO:: Async.

File::Monitor тоже выполняет эту работу.

Другие вопросы по тегам