use Capture::Tiny 'tee';
my $output = tee { system('t=1;while [ 1 -eq 1 ]; do echo hello $t; if
+ [ $t -eq 10 ]; then exit 0; fi; t=$((t+1)); sleep 1; done') };
print $_ while( <$output> );
Now, that's a first step. But think big:
The following script I whipped up creates a wrapper for 1) spawning xorisso, 2) non-blocking select its STDOUT, 3) setup a listening socket so that clients can connect and enquire about xorisso's output, 4) non-blocking select the socket, 5) check if command has finished.
use strict;
use warnings;
# Script by bliako for https://perlmonks.org/?node_id=11100979
# spawns a system command and while running it sends its output
# to a client connecting via a socket.
# when the command terminates, the program waits for a client
# to send last pending output and exits too.
# 05/06/2019
use IO::Socket::INET;
use IO::Select;
use Scalar::Util qw/openhandle/;
use POSIX ":sys_wait_h";
my $EXEC = undef;
my $keep_on = 1;
$SIG{CHLD} = sub {
waitpid(-1,WNOHANG);
$keep_on = 0;
};
my $port = 20000;
my $cmd = 't=1;while [ 1 -eq 1 ]; do echo hello $t; if [ $t -eq 10 ];
+then exit 0; fi; t=$((t+1)); sleep 1; done';
my $execpid = open($EXEC, '-|', $cmd) or die "failed to spawn command
+$cmd : $!";
die "spawning system command, $!" unless defined $execpid;
print "PID is $execpid\n";
# Listen to port
my $sock =
IO::Socket::INET->new(LocalPort => 20000,
Type => SOCK_STREAM,
Proto => 'tcp',
Listen => SOMAXCONN,
Reuse => 1,
Timeout => 1,
Blocking => 0
) or die "Can't create socket, $@";
my @cmdoutput;
my $aselect = IO::Select->new();
$aselect->add($sock);
$aselect->add($EXEC);
#local $/ = undef;
WHITER: while(){
my @clients = $aselect->can_read(1);
foreach my $aclient (@clients){
if( $aclient == $EXEC && $keep_on){
print "$0 : select the EXEC ...\n";
if( openhandle($EXEC) ){
# checking
print "spawn command lives\n";
push @cmdoutput, <$EXEC>;
} else {
print "spawn command ended\n";
push @cmdoutput, '<close>'; $keep_on = 0;
}
} elsif( $aclient == $sock ){
print "$0 : select a client via socket ...\n";
if( ! $aclient->connected() ){ $aselect->remove($aclient)
+}
$aclient = $sock->accept();
$aselect->add($aclient);
# send them a message, close connection
$aclient->print(join("",@cmdoutput));
print "$0 : got a request and send the cmd output so far.\
+n";
@cmdoutput = ();
if( ! $keep_on ){
# command has ended but wait for a client to send all
+pending output
$aclient->print("<closed>\n");
print "$0 : terminating after send client pending outp
+ut.\n";
$aclient->close();
$aselect->remove($aclient);
last WHITER
}
$aclient->close();
$aselect->remove($aclient);
}
}
}
print "$0 : done.\n";
# example use:
perl a.pl &
telnet localhost 20000
bw, bliako |