Reputation:
Greetings, I want to read through a file, go to sleep and then check if new records were written to the file. If yes I want to process the records, if no go back to sleep and check again later (in a forever loop).
I thought I could do something like this but after it reads the file the first time through the while, it never seems to pick up the new records added to the file.
open (LOG, "<log_file") or die ("could not open log_file");
for (; ;)
{
print "Record Number == $.\n";
while ($text=<LOG>)
{
chomp ($text);
print "$text\n";
}
sleep (60);
}
close (LOG);
After reading the file originally the above script just keeps printing the record number of the last record in the file. I saw somethng about a TailFile package available but it appears I don't have it and it would be difficult to get loaded at this time. I am hoping for a vanilla perl solution.
Thanks in advance.
Upvotes: 3
Views: 2618
Reputation: 1335
@jmanning2k, Do you happen to have a link for handling this? The perl cookbook has the following, which seems very weak ...
for (;;) { while () { .... } sleep $SOMETIME; seek(FH, 0, 1); }
or the IO::Handle module's clearerr method:
use IO::Seekable; for (;;) { while () { .... } sleep $SOMETIME; FH->clearerr(); }
Upvotes: 0
Reputation: 64939
This is covered by the Perl FAQ. See perldoc -q tail for the full entry. If you are willing to install a CPAN module, you should consider File::Tail.
Upvotes: 4
Reputation: 9488
That's because your while loop will terminate when the filehandle returns EOF. You'll need to clear the EOF flag before reading.
Use seek, after the while loop and the sleep.
seek(LOG, 0, 1);
That literally says: move zero bytes from current position. It won't advance in the file, but does clear the EOF condition for the next read.
You can also use the IO::Handle module and call clearerr();
use IO::Handle;
# ...
LOG->clearerr();
Lastly, if you're willing to use a tie'd filehandle, there's a File::Tail module on CPAN you can try.
Upvotes: 9