开发者

How can I asynchronously monitor a file in Perl?

开发者 https://www.devze.com 2022-12-27 05:59 出处:网络
I am wondering if it is possible, and if so how, one could create a perl script that constantly monitors a file/d开发者_JAVA技巧b, and then call a subroutine to perform text processing if the file is

I am wondering if it is possible, and if so how, one could create a perl script that constantly monitors a file/d开发者_JAVA技巧b, and then call a subroutine to perform text processing if the file is changed. I'm pretty sure this would be possible using sockets, but this needs to be used for a webchat application on a site running on a shared host, and I'm not so sure sockets would be allowed on it.

The basic idea is:

  • create a listener for a chat file/database
  • when the file is updated with a new message, call a subroutine
  • the called subroutine will send the new message back to the browser to be displayed

Thanks in advance.


Many operating systems run a service that allows applications to register a request to be notified when a file or path has been updated. This is generally called a File Alteration Monitor. See the linked wikipedia page for some systems available. Recent linux systems use Inotify, previously Dnotify or gamin were used. OS X uses FSEvents. Windows has a similar system. I don't know of any module or mechanism that works cross platform for all these systems, but there are specific modules available on CPAN, such as SGI::FAM and File::Tail::FAM.


I'd do this with a cron job and a Makefile that invoked a Perl script. The handy thing is that you get the Perl script's atime automatically as the timestamp to compare against, since the script's atime is updated when it is invoked.


use POE qw(Wheel::FollowTail);
POE::Session->create(
    inline_states => {
      _start => sub {
        $_[HEAP]{tailor} = POE::Wheel::FollowTail->new(
          Filename => "/var/log/thttpd.log",
          InputEvent => "got_log_line",
          ResetEvent => "got_log_rollover",
        );
      },
      got_log_line => sub {
        #print "Log: $_[ARG0]\n";
        parseline($_[ARG0]);
      },
      got_log_rollover => sub {
        #print "Log rolled over.\n";
      },
    }
  );

POE::Kernel->run();
exit;

#parseline()...etc.
0

精彩评论

暂无评论...
验证码 换一张
取 消