in reply to open3 question
Okay, so in your case, $in and $out are "null strings", hence they get replaced by autogenerated filehandles. Then, $err happens to be false (same thing as a "null string", you might say, but that's not what matters -- at the point where you pass it to open3, its value is false), hence it becomes a dup of the child's STDOUT.
I hadn't played with open3() much before now, so it took me a few tries to get a working demo, but here it is. First, a simple, dumb child script that writes to STDOUT and STDERR:
Then, a simple, dumb parent to run the child:#!/usr/bin/perl use strict; use IO::Handle; autoflush STDOUT 1; # had to do this, even tho Open3 doc said it woul +d be done already while (<>) { chomp; print "line $. to STDOUT: $_\n"; warn "mesg $. to STDERR\n"; }
Anyway, to answer your question: I suppose the "if ERRFH is false, set it equal to RDRFH" behavior makes the "simplest default" case come out as "STDERR eq STDOUT" because that's the way shells usually work when returning process output to an interactive user: unless the user specifies otherwise in an interactive shell, stdout and stderr are both presented to the screen.#!/usr/bin/perl use strict; use IPC::Open3; my $cmd = "test-child.pl"; my ( $in, $out, $err ); $err = "true"; # any string will do (don't use a number) my $pid = open3( $in, $out, $err, $cmd ); my ( $outlog, $errlog ); for ( 1..3 ) { print $in "data $_\n"; $outlog .= <$out>; $errlog .= <$err>; } close $in; waitpid $pid, 0; print "outlog contained:\n$outlog\n"; print "errlog contained:\n$errlog\n"; __OUTPUT__ outlog contained: line 1 to STDOUT: data 1 line 2 to STDOUT: data 2 line 3 to STDOUT: data 3 errlog contained: mesg 1 to STDERR mesg 2 to STDERR mesg 3 to STDERR
Okay, as a rationale, that probably makes no sense in the non-interactive context of a perl script. Oh well...
(update: to clarify about setting autoflush in the child, that actually makes sense: open3() can only control the properties of filehandles in the parent, and one of its big caveats is that it only works properly when the child is itself configured so as not to buffer its output. I could have done "$| = 1" in the child, instead of using IO::Handle's autoflush call, and it would work just as well.)
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: open3 question
by amw1 (Friar) on Feb 10, 2005 at 14:54 UTC |