Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: Best Way to Redirect STDERR to a Scalar

by davido (Cardinal)
on Sep 13, 2003 at 22:35 UTC ( [id://291303]=note: print w/replies, xml ) Need Help??


in reply to Best Way to Redirect STDERR to a Scalar

The first method I would propose is based on a technique I read in the Perl 5.8.0 perldoc perlfunc manpage for open. The trick discussed therein is to close the old STDERR before reopening it, redirected to a scalar.


UPDATE:
I'm sorry to say that this proposed method works only under 5.8.0 or later, as expressed in the perldoc perldelta manpage, "File handles can be opened to "in memory" files held in Perl scalars via open($fh,'>',\$variable) || ...."

However, all is not lost. Read on to my second update to see how to do it in any version using the module Tie::STDERR.


my $variable; # First, save away STDERR open SAVEERR, ">&STDERR"; close STDERR; open STDERR, ">", \$variable or die "What the hell?\n"; # Now print something to STDERR, redirected to $variable print STDERR "This is a test.\n"; # Now close and restore STDERR to original condition. close STDERR; open STDERR, ">&SAVEERR"; # Now test to see if $variable actually received the text. print "Now for the real test.\n"; print $variable;

That ought to do the trick. ...at least under 5.8.0+. It gets even more fun when you use it to redirect STDOUT to a scalar. It's too bad it didn't exist prior to 5.8.0.


UPDATE:

Under pre-5.8.0 versions of Perl (or post-5.8.0 too if you wish, though it becomes unnecessary), you could use the module: Tie::STDERR

use Tie::STDERR \$append_to_scalar;

From that point on, STDERR will be routed to the scalar. The module can also be used to redirect STDERR to email, or to a function that is called upon program exit. If you look into the module's internals you see that 'tie' is being used to tie *STDERR to the package named Tie::STDERR, and then the module is holding onto anything that would have been writen to STDERR and appending it to the scalar you supply in the use Tie::STDERR .....; line.


I hope this helps for you too.

Dave

"If I had my life to do over again, I'd be a plumber." -- Albert Einstein

Replies are listed 'Best First'.
Re: Re: Best Way to Redirect STDERR to a Scalar
by shenme (Priest) on Sep 13, 2003 at 23:57 UTC
    Unfortunately Tie::STDERR won't do what's needed.   There's this note in the POD:
    However, if you run external command (system, ``), stderr output from that process won't be caught.   It is because we tie Perl's STDERR fileglob, not the external filehandle.
    (grumble - sounded wonderful tho)
      I don't know that it's correct or safe to jump to the conclusion that Tie::STDERR won't do what's needed, as the OP didn't specify in his original post that he was trying to catch errors that come from executing external commands.

      Tie::STDERR will allow you to redirect any errors that come from Perl or Perl commands, but not from external (such as system() or `` backticks). It will even catch Perl's compiler errors, though as the POD states, the errors that it reports from the compiler aren't what you might expect to see.

      So if you're trying to redirect the output from any Perl-generated errors, or errors that you generate internally in your script, Tie::STDOUT works great. But if you want to redirect external command errors, you'll have to dig deeper.

      Dave

      "If I had my life to do over again, I'd be a plumber." -- Albert Einstein

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2024-04-18 13:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found