tags:

views:

217

answers:

5

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.

A: 

hey,

thats because you need to open() and read the file each time at a time and close it afterwards. achieving something like tail -f wont work the way you try it. it just looks fluent visually.

Haim Evgi
I tried re-opening. The problem is it starts reading from the brginning of the file again. I just want to process the new records added to the file, thanks.
+10  A: 

File::Tail is your friend.

innaM
+7  A: 

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.

jmanning2k
+1  A: 

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.

Chas. Owens
A: 

@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();
 }
hpavc