Как получить имя файла вместе с абсолютным путем к файлу, всякий раз, когда новый файл создается с использованием 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 тоже выполняет эту работу.