1
use Text::Diff;
for($count = 0; $count <= 1000; $count++){
   my $data_dir="archive/oswiostat/oracleapps.*dat";
   my $data_file= `ls -t $data_dir | head -1`;
   while($data_file){
      print $data_file;
      open (DAT,$data_file) || die("Could not open file! $!");
      $stats1 = (stat $data_file)[9];
      print "Stats: \n";
      @raw_data=<DAT>;
      close(DAT);
      print "Stats1 is :$stats1\n";
      sleep(5);
      if($stats1 != $stats2){
         @diff = diff \@raw_data, $data_file, { STYLE => "Context" };
         $stats2 = $stats1;
      }
      print @diff || die ("Didn't see any updates $!");
   }
}

Output:

$ perl client_socket.pl
archive/oswiostat/oracleapps.localdomain_iostat_12.06.28.1500.dat
Stats:
Stats1 is :
Didn't see any updates  at client_socket.pl line 18.

Can you tell me why the stats are missing and how to fix it?

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
VeerM
  • 105
  • 4
  • 11
  • 5
    I don't believe that's the code you actually ran. $data_file would have contain the name of the file followed by a newline, so open would fail, so it would die. A `chomp` would fix that. There's numerous other problems, but what's the point of commenting on something that's not your code? I strongly recommend you start by adding `use strict; use warnings;` and fix those errors. – ikegami Jun 28 '12 at 19:43
  • it has file, as you see it printed in the fist line as "archive/oswiostat/oracleapps.localdomain_iostat_12.06.28.1500.dat" – VeerM Jun 28 '12 at 19:49
  • No, it has `"archive/oswiostat/oracleapps.localdomain_iostat_12.06.28.1500.dat\n"` – ikegami Jun 28 '12 at 19:49
  • 1
    @ikegami, it is the actual code. On my Linux system, according to strace, `open(F, "newline\n")` calls `open("newline" *[sic]*, ...)`, but `stat "newline\n"` calls `stat("newline\n" *[sic]*, ...)`. You're right, it's newline trouble. Three-arg open appears to preserve the newline, FWIW. – pilcrow Jun 28 '12 at 19:54
  • so what is the fix then? – VeerM Jun 28 '12 at 19:58
  • @pilcrow, Interesting. VeeraMarni, lack of `chomp`, as previously mentioned, is the first error. – ikegami Jun 28 '12 at 22:01
  • @ikegami, see Q&A linked from my (updated) answer below... – pilcrow Jun 28 '12 at 22:02

2 Answers2

14

The real fix is File::ChangeNotify or File::Monitor or something similar (e.g., on Windows, Win32::ChangeNotify).

use File::ChangeNotify;

my $watcher = File::ChangeNotify->instantiate_watcher(
    directories => [ 'archive/oswiostat' ],
    filter => qr/\Aoracleapps[.].*dat\z/,
);

while (my @events = $watcher->wait_for_events) {
    # ...
}
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
2

Note that I'm answering your original question, why the stat() seemed to fail, rather than the newly edited question title, which asks something different.

This is the fix:

my $data_file= `ls -t $data_dir | head -1`;
chomp($data_file);

The reason this is the fix is a little murky. Without that chomp(), $data_file contains a trailing newline: "some_filename\n". The two argument form of open() ignores trailing newlines in filenames and I don't know why because two-arg open mimics shell behavior. Your call to stat(), however, does not ignore the newline in the filename, so it is stat()ing a non-existent file and thus $stats1 is undef.

Community
  • 1
  • 1
pilcrow
  • 56,591
  • 13
  • 94
  • 135
  • @picrow thans for the help. I m touching perl after a long time, thanks for quick help. And i need to correct the $stats2 which is in the if loop. This variable should be global, how should i correct this. As of now stats2 is showing empty. – VeerM Jun 28 '12 at 22:42