Is there an equivalent of `tail -f` in Perl?
I'm writing a script that listens for changes to a log file and acts appropriately. At the moment I'm using open my $fh, "tail -f $logfile |";开发者_Go百科
but ideally I don't want to use system calls.
I've tried File::Tail but it has a minimum interval of 1 second (I've tried passing less but it defaults to 1 second, even if I pass 0). I've checked the source for it and it seems to be using sleep() which takes an integer. Before I try to write my own, are there any other options?
Thanks.
- Did you know that
tail -f
also uses a 1-second sleep by default? It's true! (At least for GNU tail...) File::Tail
actually uses Time::HiRes'ssleep
function, which means that the sleep time parameter isn't an integer; you can set it to any fractional number of seconds that your system can deal with.
There's a lot of good stuff in the documentation, including an answer to this exact question. From perlfaq5's answer to How do I do a "tail -f" in perl?
First try
seek(GWFILE, 0, 1);
The statement seek(GWFILE, 0, 1) doesn't change the current position, but it does clear the end-of-file condition on the handle, so that the next makes Perl try again to read something.
If that doesn't work (it relies on features of your stdio implementation), then you need something more like this:
for (;;) {
for ($curpos = tell(GWFILE); <GWFILE>; $curpos = tell(GWFILE)) {
# search for some stuff and put it into files
}
# sleep for a while
seek(GWFILE, $curpos, 0); # seek to where we had been
}
If this still doesn't work, look into the clearerr method from IO::Handle, which resets the error and end-of-file states on the handle.
There's also a File::Tail module from CPAN.
CPAN has File::ChangeNotify
In my opinion there is nothing wrong with using tail -f
pipe like you already do. In many situations going for language purity like "no system calls" is counterproductive.
Also, I've seen problems with File::Tail
in long-running processes. Unfortunately I cannot corroborate this claim with any hard evidence since it happened quite some time ago, I did not debug the problems, replacing the use of File::Tail
with a tail -F
pipe instead.
精彩评论