Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use perl/ajax to read a file line by line while the file is written by another program?

It is similar to the question being asked hereHow to read from file line by line using ajax request while file is written by other program using java? I have a file that will be populated with command line outputs generated from a remote machine. What I would like to do is every time something gets written in the file, I want to use perl (or javascript but I am quite dubious about it) to capture it and display what is being written in an opened webpage. Ideally each line should be shown in the html as soon as it is written in the file like the way how it is generated in the terminal.

My difficulty is that I am not sure how I should do the polling - detecting something is being written in the file - and how I can capture the line at real time.

That being said, another possibility I have thought of is to change my script on the remote machine and dump the terminal output into a div of my website. This would avoid writing, reading and realtime polling but not even sure if this is possible?

like image 248
idleonbench Avatar asked Mar 11 '23 16:03

idleonbench


1 Answers

Ignoring AJAX for a second, a Perl program would normally use File::Tail.

With AJAX, you'd probably have to reimplement File::Tail. The following is a basic version:

#!/usr/bin/perl

use strict;
use warnings;

use CGI          qw( );
use Fcntl        qw( SEEK_SET );
use Text::CSV_XS qw( decode_json encode_json );

my $qfn = '...';

{
   my $cgi = CGI->new();
   my $request = decode_json( $cgi->param('POSTDATA') || '{}' );
   my $offset = $request->{offset} || 0;

   open(my $fh, '<:raw', $qfn)
      or die("Can't open \"$qfn\": $!\n");

   seek($fh, $offset, SEEK_SET)
      or die("Can't seek: $!\n");

   my $data = '';
   while (1) {
      my $rv = sysread($fh, $data, 64*1024, length($data));
      die("Can't read from \"$qfn\": $!\n") if !defined($rv);
      last if !$rv;
   }

   $offset .= length($data);

   print($cgi->header('application/json'));
   print(encode_json({
      data   => $data,
      offset => $offset,
   }));
}
like image 120
ikegami Avatar answered Apr 08 '23 06:04

ikegami