Newsgroups: comp.lang.perl
Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!zaphod.mps.ohio-state.edu!wuarchive!uunet!convex!usenet
From: Tom Christiansen <tchrist@convex.COM>
Subject: Re: How can I capture STDERR from a command executed externally
Message-ID: <1991May24.081211.21710@convex.com>
Sender: usenet@convex.com (news access account)
Nntp-Posting-Host: pixel.convex.com
Reply-To: tchrist@convex.COM (Tom Christiansen)
Organization: CONVEX Software Development, Richardson, TX
References: <4352@inews.intel.com> <1991May23.055849.6100@jpl-devvax.jpl.nasa.gov>
Distribution: usa
Date: Fri, 24 May 1991 08:12:11 GMT
Lines: 38

And for those who want to read STDERR but send STDOUT to 
a file (let's call it "kid.out"), do this:


    open (CMD_ERR, "cmd args 3>kid.out 2>&1 1>&3 3>&- |");
    while (<CMD_ERR>) {
	print "line from stderr: ", $_;
    }
    close CMD_ERR;
    warn "cmd exited $?" if $? >>= 8;

    open (KID_OUT, "< kit.out") || die "can't open kid.out: $!";
    while (<KID_OUT>) {
	print "line from stdout: ", $_;
    } 


Hmm, I just had another odd idea.  Let's not use any temp files:

 open (CMD, "3>&1 (cmd args 2>&1 1>&3 3>&- | sed 's/^/STDERR:/' 3>&-) 3>&- |");
 while (<CMD>) {
   if (s/^STDERR://)  {
     print "line from stderr: ", $_;
   } else {
     print "line from stdout: ", $_;
   }
 } 

Now Aren't you glad you had the shell to do that all for you?  Of course,
you didn't *have* to call sed, or the shell either for that matter.  The
perl-only solution I leave up as an exercise to the reader, who is
presumably less tired and more ambitious than I at 3am. :-)


--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
		"So much mail, so little time." 
