Hi waytoperl
I would side with Discipulus here and surmise that your problem is in regard to simultaneously printing the output into multiple filehandles, or multiplexing.
For me it seemed clear that using the single form of perlfunc:select would be necessary to achieve simple multiplexing. However, I managed to rework the code around the perlfunc:pipe function. Thank Strawberry (and Perlmonks) for perldoc.
Essentially, once you have selected a filehandle, the filehandle_special-variables are operational on that filehandle
Any regular output run in a perlfunc:system call will go to that output filehandle, but there, as in the code here, any redirections within the external script, will behave as scripted.
The perlfunc:pipe perlfunc:fork combo sets up a situation where you may select the output filehandle to only print to the output, or select the pipe $writer indirect filehandle, to print to both (or as many as you like) at the same time.
Best not to redirect 0,1,2 unless you understand it well. Even though I have done so here, I am very confident there are better ways. Discipulus' link to log4Perl premise is definetly worth another look.
#!/usr/bin/perl -w
use strict;
use feature qw{ say };
use File::Spec::Functions qw{ catfile };
use Fcntl;
use IO::Handle;
# special Filehandle variables,
# operate on currently selected fh
$|++;
open my $output, '>', catfile( qw( . output.txt ) )
or die q{ output open fail },$!;
my $original_selected_default_output = select $output; $|++;
select $original_selected_default_output;
my $reader = IO::Handle->new();
my $writer = IO::Handle->new();
(select($_),$|++) foreach ($reader,$writer,'STDOUT');
pipe($reader,$writer) or die "not today $!";
my $pid = fork();
if( $pid == 0 ){
close $writer;
open my $stdout, '>&', 'STDOUT'
or die 'aaaarrrggh!',$!;
my @filehandles = ( $stdout, $output );
say( 'firstly from reader' ) foreach($stdout,$output);
while(my $l = <$reader>){
foreach my $fh ( @filehandles ){
say { $fh } 'from ',$l, ' reader';
}
}continue{} # this is distilled genius
say( 'finely from reader' ) foreach( $stdout, $output );
select $original_selected_default_output ;
close $reader;
exit 0;
}elsif($pid){
close $reader;
}else{
die "there is far better error handling to be had here $!"
}
# say to ./output.txt
select $output;
say localtime(time),q{ All I need to say is use feature };
# say to both
select $writer;
say localtime(time),' using say is straightforward for simple output';
# set back to good ol' STDOUT
select $original_selected_default_output
or die "not working $!";
# clear up the pipe
close $writer;
#scrap most of todays code
#sleep 1;
say localtime(time),q{ snoozing};
say 'quick, gotta go to bed';
exit 0;
|