Dave05 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I want to capture the output of a program that prints on STDOUT. I could redirect STDOUT to a file like this:

# See the Cookbook p.263 for redirecting standard output. # Copy the STDOUT file descriptors: my $buffer_file = '/path/to/buffer.txt'; open(OLDOUT, ">&STDOUT"); open(STDOUT, "> $buffer_file") or die "Couldn't redirect STDOUT to $bu +ffer_file: $!"; # Call the script whose output I want to capture: do("/path/to/cgi/mhandler.cgi"); # Close the redirected STDOUT and restore the original: close(STDOUT) or die "Couldn't close redirected STDOUT: $!"; open(STDOUT, ">&OLDOUT") or die "Couldn't restore STDOUT: $!"; close(OLDOUT) or die "Couldn't close OLDOUT: $!";

But it would be more useful if I could capture the STDOUT directly into a $buffer variable instead of a file.

Is it possible to open a filehandle into a variable like that?

Replies are listed 'Best First'.
Re: Redirecting STDOUT to a variable
by davis (Vicar) on Sep 10, 2002 at 10:48 UTC
    You want qx (Quoted execution) or the backticks operator:
    #!/usr/bin/perl use warnings; use strict; my $output = `nslookup www.perlmonks.org`; #or qx print "=====\n"; print $output; print "=====\n";
    See perldoc perlop, and look for Quote and Quote-like Operators for more information
    Cheers
    Update: Also look for qx/STRING/ in the above manpage - it's more relevant
    Update 2: Search for "capture STDOUT" in the search box, and you'll find How to capture data from STDOUT?. If it's a simple question, it's almost certainly been asked (and answered) before, so please remember to search first.

    davis
    Is this going out live?
    No, Homer, very few cartoons are broadcast live - it's a terrible strain on the animator's wrist
Re: Redirecting STDOUT to a variable
by jmcnamara (Monsignor) on Sep 10, 2002 at 11:10 UTC

    Have a look at the IO::Scalar module which is part of the IO::Stringy distribution:
    #!/usr/bin/perl -w use strict; use IO::Scalar; my $str; tie *STDOUT, 'IO::Scalar', \$str; print "hello, world"; untie *STDOUT; print "The data is here: ",$str;

    --
    John.

Re: Redirecting STDOUT to a variable
by blssu (Pilgrim) on Sep 10, 2002 at 11:26 UTC

    Perl 5.8 has the ability to open strings (scalars) as files, but that feature does not work for capturing output of other programs -- use the backtick method above for that.

    If you want to capture the output of a subroutine or module inside your own Perl code, the string file technique works well. I'm including it here because this node is likely to turn up in a search.

    use strict; use PerlIO::scalar; my $output; my $file; if (open($file, ">", \$output)) { print $file "This is a test.\n"; close($file); print $output; }

    If you want to redirect STDOUT to a scalar, close it first and then open it connected to the string scalar. You will get an error if you try to do anything that requires a "real" file. (Calling system(...) will fail for example.)

Re: Redirecting STDOUT to a variable
by ash (Monk) on Sep 10, 2002 at 13:52 UTC
    You'd just use a TIEHANDLE.
    See perldoc tie and perldoc Tie::Handle.

    -- 
    ash/asksh <ask@unixmonks.net>

Re: Redirecting STDOUT to a variable
by antichef (Acolyte) on Sep 12, 2002 at 17:16 UTC
    You can open a handle similar to a file handle like:

    open (STDOUTHANDLE, "somecommand|"); while ($line = <STDOUTHANDLE>) { # . . . }

    note the pipe character at the end of the command.