That's one specialty for backticks only. With backticks, a new filehandle is allocated into which the STDOUT of the subprocess is diverted. But the STDERR of the subshell goes to your STDOUT.
Yes, the redirect has to be done in the source process, unless you patch your kernel with a MacFilehandle patch (three button -> one button :-) which lumps STDOUT and STDERR together at will.
Within the same perl process filehandles it's all fine:
#!/usr/bin/perl -w
use strict;
# $Id: blorfl.pl,v 0.0 2006/09/21 11:11:11 shmem Exp $
print "foo";
warn "warn";
print "\n";
__END__
qwurx [shmem] ~> perl -e 'open(STDERR,">&", STDOUT); do "blorfl.pl"' 1
+>/dev/null
qwurx [shmem] ~> perl -e 'open(STDERR,">&", STDOUT); do "blorfl.pl"' 2
+>/dev/null
foo
warn at blorfl.pl line 5.
But a subprocess invoked has two brand new filehandles for STDOUT and STDERR, which happen to be connected to the same filehandle in the parent (which the subshell doesn't know), but the process is free to buffer at lib. You have to do something with the source process, at least to have it make STDOUT unbuffered if you want the two streams in synch.
qwurx [shmem] ~> perl -le 'open(STDERR,">&", STDOUT); system "perl blo
+rfl.pl"' 1>/dev/null
qwurx [shmem] ~> perl -le 'open(STDERR,">&", STDOUT); system "perl blo
+rfl.pl"' 2>/dev/null
warn at blorfl.pl line 5.
foo
While redirection works as expected, note the reverse order of 'warn' and 'foo' due to buffered STDOUT.
<update>
BTW, the FAQ entry you quoted should read like this for clarity
This fails because the open() makes STDERR go to where STDOUT was going at the time of the open(). The backticks then make the subshell's STDOUT go to a string, but don't change the subshell's STDERR (which still goes to the old STDOUT).
<update>
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
|