#!/usr/bin/perl
use strict;
use warnings;
my ($buf);
{
local *STDOUT;
open( STDOUT, '>', \$buf ) or die "Write to buffer failed\n";
mysub();
}
print "buffer: $buf\n";
sub mysub{
print "mysub output\n";
}
The sub's printouts go to STDOUT, which is to my screen. Using the above code, STDOUT is redirected to the variable $buf so no printouts go to the screen. I want to be able to get a copy of the data that is going to STDOUT without redirecting STDOUT. In other words, I want the data to go to the variable "$buf" in the above code and to continue to go to the screen. Is there a way to do this?
I could just print the variable $buf after its done too. However, some of data are very big and the sub that I'm trying to capture takes a long time to execute. During that time, no printouts goes to the screen so there's nothing indicating that the program is still executing correctly.
Also, is there a way to capture STDERR at the same time? I mean, can I redirect a copy of STDERR and STDOUT to the same $variable? I was able to do it to two variables, but then, I don't know which error occur when. It would be nice to have the STDOUT and STDERR in the same spot in chronological order so I know which error occurred after which STDOUT data.
Thanks for any help.
MNJ
Phil
However, I cannot modify the sub whose outputs I want. Also, I don't have the module and doubt that the admin would install it.
MNJ
IO::Tee is pure Perl code. If you can copy a file onto the same machine you're running your code (and if you can't, one wonders how you're getting your code there . . .) you can "install" your own copy. Make an IO directory somewhere, put the IO::Tee source in Tee.pm, point perl at the directory containing IO via either PERL5LIB, a command line -I switch, or the standard lib module.
However, I cannot modify the sub whose outputs I want.
Not a problem.
#!/usr/bin/perl
use strict;
use warnings;
use IO::Tee ();
my $buf;
{
open(my $buf_fh, '>', \$buf )
or die "Unable to create a write-to-memory handle: $!\n");
my $tee = IO::Tee->new(\*STDOUT, $buf_fh);
my $old_select = select($tee);
mysub();
select($old_select);
}
mysub();
}
print "buffer: $buf\n";
sub mysub{
print "mysub output\n";
}
The above is untested. If it doesn't work, I'm sure it's fixable.
Update: Tested (as much as I can with Perl v5.6.1) and fixed. Keep in mind the previously discussed [id://546986|caveats] to using select.
I don't have the module and doubt that the admin would install it.
Then install it in your account. This is super easy in this case since the module consists entirely of one .pm.
Before test scripts are executed, I do start UNIX's "script" to capture the log. From my limited experience with "script", it seems that the log file does not get written to until the "script" performs an "exit". I suppose I could call "script" inside of a perl script. Would I have problems identifying which session is the original session and which is the "script" session?
MNJ
Maybe something like IO::Tee would help?
-xdg
Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.
I feel even dirtier suggesting you look into importing your print function into CORE::GLOBAL.
It's definitely dangerous, but hey, the functionality is there.
package NewHandle;
require Tie::Handle;
@ISA = qw(Tie::Handle);
sub WRITE { $self = shift; $main::text .= shift; }
sub TIEHANDLE { bless { }, shift; }
package main;
use strict;
use warnings;
our $text;
print "before: $text\n";
{
local *STDOUT;
tie *STDOUT, 'NewHandle';
mysub();
}
print "after: $text\n";
sub mysub {
print "mysub", " output\n";
}
1;
"I could just print the variable $buf after its done too. However, some of data are very big and the sub that I'm trying to capture takes a long time to execute..."
perlmonks.org content © perlmonks.org and Fletch, gam3, ikegami, jpeg, mnj200g, philcrow, TedPride, xdg
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03