Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: capturing output from open |

by fizbin (Chaplain)
on Oct 19, 2005 at 16:07 UTC ( [id://501347]=note: print w/replies, xml ) Need Help??


in reply to capturing output from open |

First off, for the case of catching STDERR when running another program, check out IPC::Open3, which has been in the standard perl distribution for years.

In the case of running other perl code and capturing the standard error output from it, say your second case above, you can do something like this in perl 5.8 and higher:

open my $savederr, '>&', \*STDERR; my $module_stderr = ''; open(STDERR, '>', \$module_stderr); SomeFunkyModule::sub_that_spews_to_stderr(); open(STDERR, '>&', $savederr); # process the stuff in $module_stderr

In older perls, you can do the same thing with IO::String.

--
@/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/; map{y/X_/\n /;print}map{pop@$_}@/for@/

Replies are listed 'Best First'.
Re^2: capturing output from open |
by DrWhy (Chaplain) on Oct 19, 2005 at 17:00 UTC
    First off, for the case of catching STDERR when running another program, check out IPC::Open3, which has been in the standard perl distribution for years.

    Right, but this is not apropos to my question. By the way, whenever I think of IPC::Open3, I think instead of IPC::Run which is a much more tractable solution to the same problem set IMO</preaching>

    As for your proposed solution. It almost works. I n order for STDERR to be effectively repointed to $module_stderr you have to explicitly close the filehandle and then reopen it. (this is a special requirement that only applies to STDOUT and STDERR when being repointed to an in-memory file). After adding this it does appear that STDERR is in fact repointed somewhere, but it's not clear to me where. It certainly isn't going into that in-memory file variable ($module_stderr). However, if you repoint STDERR to a real file rather than one of these funky in-memory file scalars, then the stderr does in fact end up in that file. Here is an example script which demonstrates the difference

    my $module_stderr = ''; close STDERR; open(STDERR, '>', \$module_stderr); open F, "perl -e \"warn 'hi'\" |" or die "$!"; while( <F>) { print 'out -> '.$_."\n"; } close F; print "err -> ". $module_stderr; print "\n"; open(STDERR, '>', 'testfile') or die "$!"; open F, "perl -e \"warn 'hi'\" |" or die "$!"; while( <F>) { print 'out -> '.$_."\n"; } close F; close STDERR; print "err -> ". `cat testfile`;

    The output I get on my setup (Windows XP, ActivePerl 5.8.7) is:

    err -> err -> hi at -e line 1.
    I'm not sure where the standard err out is going in the first case; it's not in the variable and it doesn't show up in the normal terminal output either. Maybe it's just going to /dev/null or somewhere else in the ether. Now if I could just figure out a way to get this to work without using a temporary file, I'd be a happy camper...

    --DrWhy

    "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

      You could pipe STDERR to another or the very same script.

      see perldoc perlipc and search for Safe Pipe Opens.


      s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
      +.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2024-04-19 15:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found