Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: capturing STDERR within a script

by RhetTbull (Curate)
on Mar 26, 2003 at 13:18 UTC ( [id://245916]=note: print w/replies, xml ) Need Help??


in reply to capturing STDERR within a script

My favorite way of doing this is to use Filter::Handle. The following snippet that should do what you want (that is, send all STDERR output to an array called @errors).
#!/use/bin/perl use strict; use warnings; use Filter::Handle qw(subs); my @errors; #global to hold the output of STDERR sub filter_errors { #sub for Filter::Handle #copies everything sent to STDERR to global @errors #and then sends it on to STDERR local $_ = "@_"; push @errors, $_; $_; } #set up the filtering with Filter::Handle Filter \*STDERR, \&filter_errors; #test it print "Hello world\n"; print STDERR "This is my first error\n"; print "Goodbye world\n"; print STDERR "This is my second and final error\n"; UnFilter \*STDERR; #unfilter the output now that we're done if (@errors) { print "I got the following errors:\n"; print " $_" foreach (@errors); }

Replies are listed 'Best First'.
Re: Re: capturing STDERR within a script
by bart (Canon) on Mar 26, 2003 at 13:49 UTC
    That doesn't seem to want to work for me. It doesn't do a thing. Messages printed to STDERR still get printed, and @errors remains empty.

    If anybody feels like enlightening me to what's going on, please do.

      Hmm, not sure what the problem is. Here's what it does on my system. I've used this technique several times in the past with good success.
      $ perl -v This is perl, v5.6.1 built for MSWin32-x86-multi-thread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2001, Larry Wall Binary build 631 provided by ActiveState Tool Corp. http://www.ActiveS +tate.com Built 17:16:22 Jan 2 2002 $ perl pmerr.pl Hello world This is my first error Goodbye world This is my second and final error I got the following errors: This is my first error This is my second and final error
      Instead of

      $_;

      as the last line of the sub, try

      ()

      It has to do with the return value of the sub, which is $_ in this case, and need to be an empty list if you want no output. The return value of the sub needs to be a list suitable for processing by the original file handle. In this case silence is an empty list.

      If all you want to do is capture the output, not process it, use the code from the Filter::Handle module

      Filter \*STDERR, sub {push @DATA, "@_"; ()};

      noisy stuff occurs...

      UnFilter \*STDERR;

      @DATA now holds all the noise emitted on STDERR.

      What version of perl are you using? I just tried the above example with perl 5.8.0 on cygwin and it displayed the behavior that you stated -- @errors was empty. This is the first time I've noticed this. A different Filter::Handle snippet caused 5.8.0 to coredump. I wonder if it's a bug in perl or a bug in Filter::Handle that broke with perl 5.8.0. Anyone else have any luck running Filter::Handle with perl >= 5.8.0?
        There's no need for you to just focus on 5.8.x — well, except for that coredump, of course... I've got a plain perl5.6.1 for Windows from Indigostar. That is a binary distribution which is virtually 100% compatible with Activeperl.

        What I'd rather think is that the way the script is invoked, matters. I usually call scripts from within my text editor, and STDOUT/STDERR are captured by a tool program in order to display the result in an editor window. What's more, I redirect STDERR to STDOUT from withing perl, from withing a little module.

        Aha. When I run it from the DOS prompt, without redirection, it works as you said it would. But when I add

        open STDERR, ">&STDOUT";
        to the top of the script, it fails.

        The lesson to be learned is that capturing file handles, and maybe STDERR and STDOUT in particular, can be tricky if some redirecting has already been done on the handles before that.

Log In?
Username:
Password:

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

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

    No recent polls found