Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Synchronizing STDERR and STDOUT

by OfficeLinebacker (Chaplain)
on Sep 21, 2006 at 12:30 UTC ( [id://574112]=note: print w/replies, xml ) Need Help??


in reply to Synchronizing STDERR and STDOUT

Greetings, esteemed monks!

Isn't this one of those currently unsolvable problems? I've been trying to separately but synchronously handle

STDOUT and STDERR for months now. The closest I've gotten is (big program follows)

#!/opt/local/bin/perl -w ###################################################################### +############# #Script to run jobs that are to be logged on "cron output page." Norm +ally used by calls from the cron daemon, #it may be used interactively to capture output for posting on web by +report.pl. ###################################################################### +############# #Edited JWC 7/26/06 with the use of special output-handling functions +for cleaner output. ###################################################################### +############# #Edited JWC 8/19/06 to know which user is running it (before just assu +med it was m1jwc03) ###################################################################### +############# #Edited JWC 9/20/06 to compress log file (strip blank lines with sed) #This is because after playing with the handlers for the different kin +ds of output, I still saw #blank lines. It's useful to compare the start and finish times of cr +on jobs (finish time is #assumed to be the last mod time of the log file) and periodically run +ning sed on the files #in the directory would ruin that. Thus, the sedding of the files by +this program. ###################################################################### +############# use IPC::Run qw( run ); use File::Basename; use strict; #$ENV{'IPCRUNDEBUG'} = basic; #need two arguments: script to run and mailing list (comma-separated m +1 ids) $#ARGV == 1 || die "Error: Need exactly two arguments!\n"; #( $base, $dir, $ext ) = fileparse( $ARGV[0], '\..*' ); my @fp = fileparse( $ARGV[0], '\..*' ); my $base=$fp[0]; my $dir=$fp[1]; #Do some machinations to create a unique overall log file my @now = localtime; #months returned by localtime() are zero-indexed. #got to pad the zeroes for the time/date elements my $mo = sprintf( "%02d", $now[4] + 1 ); my $d = sprintf( "%02d", $now[3] ); my $y = $now[5] + 1900; my $h = sprintf( "%02d", $now[2] ); my $mi = sprintf( "%02d", $now[1] ); #changed this line to reflect hosting it locally JWC 7/20/06 my $workdir = "/fst/prod1/lib/cron/logs"; #$workdir="/fst/prod1/lib/cron/logs"; my $me = `whoami`; chomp($me); my $logfile = "$workdir/$base-$y$mo$d.$h$mi.$me.log"; open( LOG, ">$logfile" ) || die "Error: Could not open $logfile: $!\n +"; $|++; my $oldfh = select(LOG) || die "Error: Could not select LOG: $!\n"; #got rid of \n prefix to get rid of extra space -- #RegExp in report.pl does not need this to be on a line by itself. JWC + 7/26/06 my $endrun = "*-*-end_run-*-*"; $|++; print "*-*-begin_run-*-*\n"; ( my $distlist = $ARGV[1] ) =~ s/,/ /g; print "*-*-on_error $distlist-*-*\n"; chdir("$dir"); my @cmd = $ARGV[0]; #$SIG{CHLD} = sub { #removed 9/12/06 always seemed to occur at the end and told me nothing +. #print "NOTE: in sig{CHLD}\n"; # if (waitpid($pid, 0) > 0){sleep(1);}; #}; #die turned to warn, had $& in there when I should have had $? as the +return value 6/7/6 JWC { run(\@cmd, '>pty>', \&stdhandler, '2>', \&errhandler ) or warn("Error executing child? Child returned $?. Child returned ".($? >> 8)." and died from signal number ".($? & 127) +." Core dump status: ".($? & 128)." dollar bang is ".$!."\n"); } print $endrun; #have to put in this cos we may have something to say after the log is + closed now JWC 9/20/06 select($oldfh); close(LOG); #Gets rid of newlines in log file added JWC 9/29/06 my $stat=system("sed -i '/^\$/d' $logfile"); ($stat) && print "sed returned $stat; $?; $!; $^E"; sub stdhandler { #moved this to before anything else JWC 9/15/06 chomp $_[0]; #for HTML compatibility JWC 8/4/06 #oops this messes up my HTML input in the scripts (like divider span +s and such) JWC 8/7/06 #$_[0] =~ s/</&lt;/g; #$_[0] =~ s/>/&gt;/g; #used to be $_[0] =~ s/\^M//g; JWC 8/24/06 $_[0] =~ s/\r//g; #added space before and after the > signs. Also, Matlab tends to cr +eate them in pairs.8/24/06 JWC $_[0] =~ s/^\s*(\s*>>\s*)+\s*$//g; &trim; #added this 8/1/06 to further eliminate blank lines JWC #Moved this last in the order 8/24/06 JWC $_[0] =~ s/^$//g; $_[0] && print "$_[0]\n";# : print "empty string\n"; } sub errhandler { chomp $_[0]; #for HTML compatibility JWC 8/4/06 $_[0] =~ s/</&lt;/g; $_[0] =~ s/>/&gt;/g; &trim; $_[0] && print "<span id='stderr'>$_[0]</span>\n";# : print "empty s +tring\n"; } sub trim { @_ = $_ if not @_ and defined wantarray; @_ = @_ if defined wantarray; for (@_ ? @_ : $_) { s/^\s+//, s/\s+$// } return wantarray ? @_ : $_[0] if defined wantarray; }
It's obviously quite rough and for normal programs (Perl scripts that run FAME, SAS, etc), it's close enough, but if you run a program like
#% is the modulo operator so it's switching back and forth between eve +n and odd numbers $|++; $\="\n"; for (my $i=0; $i < 100; $i++){ if ($i % 2){ print STDERR $i; } else {print $i;} }
I get blocks of like 10 even numbers, then 12 odd numbers, then 15 even, then 8 odd, etc.

My apologies if this is not helpful and/or I have misunderstood your problem. Good luck.

Good luck.

_________________________________________________________________________________

I like computer programming because it's like Legos for the mind.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://574112]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2024-04-26 08:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found