Просмотр нескольких файлов с inotify в perl - PullRequest
3 голосов
/ 15 марта 2011

Мне нужно посмотреть несколько файлов в Perl, и я использую Linux :: Inotify2 .Однако я сталкиваюсь с проблемой, заключающейся в том, что первый просматриваемый файл необходимо изменить и нажать, затем второй, затем первый и т. Д. И т. Д.

Например, если второй файл изменяется перед первым, он не будетсработать, или если первый запускается два раза подряд, а второй не запускается между ними.

Этот раздел кода, который я использую, имеет эту проблему.

my $inotify = new Linux::Inotify2;
my $inotify2 = new Linux::Inotify2;
$inotify->watch ("/tmp/rules.txt", IN_MODIFY);
$inotify2->watch ("/tmp/csvrules.out", IN_MODIFY);

while () {
  my @events = $inotify->read;
  unless (@events > 0){
    print "read error: $!";
    last ;
  }

  foreach $mask (@events) {
    printf "mask\t%d\n", $mask;

    open (WWWRULES, "/tmp/rules.txt");

    my @lines = <WWWRULES>;
    foreach $line (@lines) {
      @things = split(/,/, $line);
      addrule(@things[0], @things[1], @things[2], @things[3], trim(@things[4]));
      print "PRINTING: @things[0], @things[1], @things[2], @things[3], @things[4]";
      close (WWWRULES);
      open (WWWRULES, ">/tmp/rules.txt");
      close (WWWRULES);
    }
  }

  my @events2 = $inotify2->read;
  unless (@events2 > 0){
    print "read error: $!";
    last ;
  }
  foreach $mask (@events) {
    printf "mask\t%d\n", $mask;
    open (SNORTRULES, "/tmp/csvrules.out");

    my @lines2 = <SNORTRULES>;
    foreach $line2 (@lines2) {
      @things2 = split(/,/, $line2);
      addrule("INPUT", @things2[0], @things2[1], @things2[2], trim(@things2[3]));
      print "PRINTING: INPUT, @things2[0], @things2[1], @things2[2], @things2[3]";

      close (SNORTRULES);
      open (SNORTRULES, ">/tmp/csvrules.out");
      close (SNORTRULES);
    }
  }
}

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

Спасибо за любую помощь!

Ответы [ 2 ]

9 голосов
/ 15 марта 2011

Один объект inotify может обрабатывать любое количество часов.Это одно из преимуществ inotify перед старым и теперь устаревшим dnotify.Поэтому вы должны сказать:

my $inotify = Linux::Inotify2->new;
$inotify->watch("/tmp/rules.txt", IN_MODIFY);
$inotify->watch("/tmp/csvrules.out", IN_MODIFY);

Затем вы можете увидеть, какие часы были запущены, проверив свойство fullname объекта события:

while () {
  my @events = $inotify->read;
  unless (@events > 0){
    print "read error: $!";
    last ;
  }

  foreach my $event (@events) {
    print $event->fullname . " was modified\n" if $event->IN_MODIFY;
  }
}

Большая проблема заключается в том, что вашКод изменяет те же файлы, которые вы смотрите для изменений.Когда /tmp/rules.txt изменяется, вы открываете его, читаете, а затем усекаете его, что вызывает другое уведомление об изменении, начиная весь процесс заново.В общем, это трудно решить без условий гонки, но в вашем случае вы можете просто проверить наличие пустого файла (next if -z $event->fullname).

0 голосов
/ 15 марта 2011

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

Другой вариант, который может работать, а может и не работать для вашего приложения, - это установить для вашего tempdir что-то более конкретное и сохранить все файлы, над которыми вы там работаете, а затем просто просмотреть каталог в целом, что затем Требуется только 1 объект inotify, если я читаю это право. (Я ничего не делал с этим модулем, в частности, но у меня есть довольно хорошее представление о том, как он работает, подключая системные вызовы к файловой системе).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...