1

I am trying to monitor the output of an external command with AnyEvent::Subprocess:

use feature qw(say);
use strict;
use warnings;

use AnyEvent::Subprocess;

my $job = AnyEvent::Subprocess->new(
    delegates     => [ 'StandardHandles', 'CompletionCondvar' ],
    code          => 'myscript.pl',
);
my $run = $job->run;
my $condvar = $run->delegate('completion_condvar');

$run->delegate('stdout')->handle->on_read(
    sub {
        my ( $handle ) = @_;
        my $line = $handle->rbuf;
        chomp $line;
        say "Got output: '$line'";
        $handle->rbuf = ""; # clear buffer
      }
);
my $done = $condvar->recv;

In general, I do not have access to the source code of the external script, so I cannot insert commands like STDOUT->autoflush(1) into the script (if the script happens to be a Perl script).

Here is the test script I used for testing:

myscript.pl:

use feature qw(say);
use strict;
use warnings;

#STDOUT->autoflush(1);
sleep 1;
say "data 1";
sleep 1;
say "data 2";
sleep 1;
say "data 3";

The output is coming all at once after myscript.pl finishes. I want to print each line from myscript.pl as it becomes available. How can this be done without modifying myscript.pl ?

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • 3
    Would `unbuffer` or a pseudo-terminal (pty) help, like on [this page](https://stackoverflow.com/q/54538273/4653379) – zdim May 07 '19 at 09:00
  • @zdim Yes this seems to work: `sudo apt-get install expect`, and then using `unbuffer` with `myscript.pl`. Thanks for the link! – Håkon Hægland May 07 '19 at 09:11

0 Answers0