Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Redirecting STDOUT

by tame1 (Pilgrim)
on Jun 14, 2002 at 13:30 UTC ( #174507=perlquestion: print w/ replies, xml ) Need Help??
tame1 has asked for the wisdom of the Perl Monks concerning the following question:

I find myself in need of a way of redirecting/capturing STDOUT, but from within and program instead of from the command line.

In detail, here is the problem. We use a home grown templating system in which the template holds some perl and lots of html, with a bunch of $href->{somekey} entries.
That template is slurped up, and then eval'ed (with $href having been created/filled before the slurp and eval).

The slurped template can be edited by non-programmers, so for safety we 'use Safe'. Here is the code so far:
my $code; my $compartment = new Safe; $compartment->share('$href'); $code = $compartment->reval($$file); if ($@) { _sAbort( $r, "Restricted eval failed! Unable to compile format of +type $type:", $@ ); return DONE; }
The real problem now comes up. ANY use/call of $code->($href) will activate the print statements inside the slurped file. This was fine with the following:
$r->send_http_header('text/html'); $code->($href); return DONE;
But now I am trying to instead grab the output of $code and stick it as text into an email. (You guessed it - I'm trying to email generated web pages - HTML email, yuck!).

Surfing through the various books, I find no simple way to redirect STDOUT to a variable for capture. The following code failed miserably:
my $open_err; my $data; open(OUTPUT, "$code->($href) |") or $open_err = $!; if ($open_err) { _sAbort($r,"Cannot open a pipe",$!); return DONE; } local $/ = undef; $data = <OUTPUT>; close(OUTPUT);
Any of you geniouses know offhand how I can get this darned HTML output from the code ref $code into a simple variable so i can give it to MIME::Lite as data? Much gracious bowing and licking of boots are offered to the one who can solve this for me!

What does this little button do . .<Click>; "USER HAS SIGNED OFF FOR THE DAY"

Comment on Redirecting STDOUT
Select or Download Code
Re: Redirecting STDOUT
by Dog and Pony (Priest) on Jun 14, 2002 at 13:50 UTC
    I am not sure if this will help you, but you can find several (mine and some others) takes on capturing STDOUT at STDOUT::Capture - manipulate STDOUT.
    You have moved into a dark place.
    It is pitch black. You are likely to be eaten by a grue.
Re: Redirecting STDOUT
by SarahM (Monk) on Jun 14, 2002 at 13:54 UTC
    Here is a trick I've used before. I know it works on windows...but I haven't tried it on unix. You'll need to download IO::Scalar, it comes with IO-stringy.
    use IO::Scalar; my $output; tie (*STDOUT, 'IO::Scalar', \$output); # Use this to capture STDOUT print "testout\n"; untie *STDOUT; # Use this to return STDOUT to normal print "my output='$output'";
    I hope this works for you.
      I never thought of tieing the variable... this is how I use IO::Scalar when I wish to redirect output.
      It's actually more useful for when you just need to have output to a variable rather than to some file handle:

      use IO::Scalar; my ( $STD1 $STD2 ); $STD1 = new IO::Scalar \$STD2; select $STD1; print <<DONE; blah blah blah All this is being appended to the $STD2 variable So some more text here and we are... DONE open FILE, ">test.txt"; print FILE $STD2; close FILE;
      Yes, odd example since you could have just used:

      open FILE, ">test.txt"; select FILE; print <<DONE; all that stuff again. I am DONE

      But you get the point...

Re: Redirecting STDOUT
by Anonymous Monk on Jun 14, 2002 at 14:21 UTC
    I know how to redirect STDOUT to a file

    open (STDOUT, ">>myfile.log");
    Works just fine for STDERR also!

    To redirect into a variable, perhaps you can try

    @LINES = <STDOUT>;
Re: Redirecting STDOUT
by Abigail-II (Bishop) on Jun 14, 2002 at 14:44 UTC
    If you are on a Unix like system, you can use open my $fh => "|-" and open my $fh => "-|" as described in perlipc. Also very useful for post processing output (or preprocessing input) without changing your existing program.


(RhetTbull) Re: Redirecting STDOUT
by RhetTbull (Curate) on Jun 14, 2002 at 16:56 UTC
    This question comes up a lot... I know I've answered it at least eight times. As always, my recommended solution is to use Filter::Handle. It does a great job, requires minimum changes to existing code, and works with file handles other than STDOUT/STDERR.
      And, as pointed out in its documentation, there are things it cannot catch. The most common of which are system calls.
Re: Redirecting STDOUT
by BUU (Prior) on Jun 15, 2002 at 18:43 UTC
    Is it to late to point out that there are tons of very nice templating engines already available, from html::template to ePerl? For a quick overview, you can look at "", which describes many of the common engines out there.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://174507]
Front-paged by Steve_p
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (15)
As of 2015-05-26 17:10 GMT
Find Nodes?
    Voting Booth?

    In my home, the TV remote control is ...

    Results (508 votes), past polls