Open3 with nonblocking reads

R

R.Schuller

I'm currently trying to execute a script within a script,
writing the STDOUT and STDERR in the same logfile, every
single line should contain if it's STDOUT or STDERR [E],
but i need also the actual timestamp when the STDERRs and
STDOuts were passed to the logfile. Later on, i can sort
the logfile chronological and see exactly when the script
began to run wild. I dont want to wait until the inner script
has ended, if possible I need live feedback from the script
to handle with STDOUT and STDERR and have an actual timestamp
(else all timestamps would be the same which is not my intention).
My Problem now is with my old code i could distinguish STDOUT and
STDERR quite well, but timestamp is the same, in the following code
i tried to prevent blocking by using a solution described in
perl-cookbook. As it is now I dont even get more then the first
line of STDERR at all into the logfile.

Is there a solution to write STDOUT and STDERR including actual time
and status if STDERR or STDOUT into a file while the inner script
is running? e.g. it would take 4hours to execute inner script and
i need STDOUT and STDERR while runningtime of this script. And to
make it more complicated... the inner script should not be changed!
It must be a code that can execute any old scripts that produce
STDOUT and STDERR.

Bye
Ralf

code itself:

#!/usr/bin/perl
use strict;
use diagnostics;
use warnings;
use English;
use IPC::Open3;

my $actualtime;
my $output;
my $rin;
my $nfound;
my $rout;
my $cmd=shift;
open (LOGFILE, ">>logfile") or die "Couldn't open logfile : $!\n";
my $pid = open3(*HIS_IN, *HIS_OUT, *HIS_ERR, $cmd) or die "Couldn't
open $cmd : $!\n";
close (HIS_IN);
###Perl-Cookbook, Chapter 07/14
###Reading from many filehandles without blocking
$rin = '';
#repeat next line for all filehandles to poll
vec($rin, fileno(HIS_OUT), 1) = 1;
vec($rin, fileno(HIS_ERR), 1) = 1;
$nfound = select($rout=$rin, undef, undef, undef);
if ($nfound) {
# input waiting on one or more of those 2 filehandles
if (vec($rout,fileno(HIS_OUT),1)) {
$output= <HIS_OUT>;
$actualtime=time;
print LOGFILE "$actualtime $output";
}
if (vec($rout,fileno(HIS_ERR),1)) {
$output= <HIS_ERR>;
$actualtime=time;
print LOGFILE "$actualtime [E] $output";
}
}
close (LOGFILE);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top