in reply to capture child process STDOUT/STDERR on Win32

Some sample code that runs an exe without invoking a shell, capturing the command return code, $rc, and the command stdout and stderr folded into a file, ff.tmp:

use strict; use warnings; my $outfile = 'ff.tmp'; my $exe = $^X; my @args = ( 'perl', '-e', 'print qq{to stdout};print STDERR qq{to +stderr}' ); print "here we go, running '$exe'\n"; print STDERR "here we go to stderr\n"; open(SAVOUT, ">&STDOUT") or die "error: save original STDOUT: $!"; open(SAVERR, ">&STDERR") or die "error: save original STDERR: $!"; open(STDOUT, '>', $outfile) or die "error: create '$outfile': $!"; open(STDERR, '>&STDOUT') or die "error: redirect '$outfile': $!"; system { $exe } @args; my $rc = $? >> 8; open(STDOUT, ">&SAVOUT") or die "error: restore STDOUT: $!"; open(STDERR, ">&SAVERR") or die "error: restore STDERR: $!"; close(SAVERR) or die "error: close SAVERR: $!"; close(SAVOUT) or die "error: close SAVOUT: $!"; print "rc=$rc\n"; print STDERR "rc=$rc to STDERR\n";

Should work fine on both Windows and Unix.

Replies are listed 'Best First'.
Re^2: capture child process STDOUT/STDERR on Win32
by Ywleskvy (Initiate) on Jul 29, 2008 at 08:04 UTC
    I'm so used to packages being wrapped DLLs it didn't even occur to me that I could just copy and paste the code. I'll look into that.

    I'd thought of juggling stderr and stdout to take advantage of the fact children inherit those file handles, but I'd really like a cleaner way. Not having open(FH, '-|') on Win32 seems like a major oversight, so I was hoping there was a trivial work-around I just didn't know about.

    Thanks all.