How do I redirect STDERR to the same process file handle as the one I select()
ed STDOUT to?[1]
This successfully redirects STDERR to STDOUT (both lines getting printed to STDOUT):
#!/usr/bin/perl
open( STDERR, '>&', STDOUT );
print "Output to STDOUT\n";
print STDERR "Output to STDERR (redirected to STDOUT)\n";
This successfully pipes STDOUT to a pager (less
in this case), while STDERR still gets written directly to the terminal. (You see STDOUT first, paged, and once you exit the pager, you see the STDERR line.)
#!/usr/bin/perl
open( my $pager, '|-', 'less' );
select( $pager );
print "Output to STDOUT (redirected to 'less')\n";
print STDERR "Output to STDERR\n";
I would like to combine the two -- have STDERR piped to the same pager as STDOUT.
This does not work, I get the same results as in 2). (Funnily enough, if I pipe the script output to less
again -- as in ./testme.pl | less
-- the outputs are combined on STDOUT. But STDERR is not put through the pager process opened by the script itself.)
#!/usr/bin/perl
open( my $pager, '|-', 'less' );
select( $pager );
open( STDERR, '>&', STDOUT );
print "Output to STDOUT\n";
print STDERR "Output to STDERR (gets redirected to STDOUT but not to 'less')\n";
This does not work, STDERR output vanishes completely:
#!/usr/bin/perl
open( my $pager, '|-', 'less' );
select( $pager );
open( STDERR, '>', $pager );
print "Output to STDOUT\n";
print STDERR "Output to STDERR (but does not show up anywhere)\n";
How do I redirect STDERR to the same process file handle as the one I select()
ed STDOUT to?[1]
[1]: In the actual program, I am checking that STDOUT / STDERR are not redirected by the caller already. I left those checks out of the examples for brevity.
Should select()
be the problem here, I'd be happy with achieving the same effect -- STDOUT and STDERR piped to the same pager process -- without select()
.
Target platforms include Git Bash for Windows, which severely restricts the availability of additional modules. An ideal answer would work without use
ing e.g. IPC::Open
.
How do I redirect STDERR to the same process file handle as the one I select()ed STDOUT to?
The following works for me:
use v5.38;
my $pid = open( my $pager, '|-', 'less' ) or die "Can't start less: $!";
{
local *STDOUT = $pager;
local *STDERR = $pager;
#select( $pager );
print "Output to STDOUT\n";
print STDERR "Output to STDERR\n";
}
close $pager;
Case #3: open( STDERR, '>&', STDOUT );
this duplicates STDOUT into STDERR, so it could have worked but for some reason it does not work together with select
Case #4: open( STDOUT, '>', $pager );
This opens STDOUT
in write mode to a file name given by $pager
. So this does not duplicate any descriptor