conrad has asked for the wisdom of the Perl Monks concerning the following question:
I've a script (on Linux) whose output I'd like to automatically record to a file at the same time as display on the terminal. The traditional approach to this is along the lines of
open STDOUT, "|tee '$outfile'" or die ...
This doesn't seem to interact brilliantly with some SIGINT handling I'm doing though. I was looking for alternative methods and found an old module Local::TeeOutput (not on CPAN), which looks great but seems a bit long in the tooth. Using it caused some deep weirdness to crop up elsewhere (Module::Pluggable, which I'm also using, started to die looking for xyz::SUPER) so I continued looking. I've now come up with the following, which appears to work, but I have to admit my understanding of file globs etc is not deep enough. I'd like to know whether you think it's a reasonable solution or will come back to bite me in subtle but horrible ways. All I'm seeking to record is my Perl process's stdout/stderr, so I don't mind that this doesn't record subprocesses' output (but would be interested to hear of solutions that would):
use IO::Tee; my $outfile = "test.out"; # Traditional approach: #open STDOUT, "|tee '$outfile'" or # die "Couldn't tee STDOUT to log file '$outfile': $!"; # Possible alternative? open STDOUT2, ">&=STDOUT" or die "Failed to alias STDOUT: $!"; *STDOUT = IO::Tee->new(\*STDOUT2, ">$outfile") or die "Failed to tee to aliased STDOUT and '$outfile': $!"; print "Test 1.\n"; system("echo Test 2."); # Don't really care that this isn't recorded
(Note before the above glob assignment, I tried my $tee_out = IO::Tee->new(...); open STDOUT, ">&", $tee_out or die ...;, but that just didn't work: it stringified $tee_out and used it as a filename.)
(Also note that if I don't alias STDOUT to STDOUT2 first, and instead assign a tee to STDOUT to STDOUT, it segfaults - Local::TeeOutput seems to cope with that kind of possibly-on-the-face-of-it recursive assignment though.)
I've already found one way this breaks: things like run3() don't have a valid STDOUT file descriptor to save when invoking children. Further comments/suggestions welcome though.
Thanks for your time,
Conrad
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: "tee"ing my own stdout/stderr
by ikegami (Patriarch) on Jun 07, 2010 at 16:45 UTC | |
by conrad (Beadle) on Jun 07, 2010 at 17:31 UTC | |
|
Re: "tee"ing my own stdout/stderr
by salva (Canon) on Jun 07, 2010 at 14:40 UTC | |
by conrad (Beadle) on Jun 07, 2010 at 15:45 UTC | |
by salva (Canon) on Jun 08, 2010 at 08:25 UTC | |
|
Re: "tee"ing my own stdout/stderr
by jdporter (Paladin) on Jun 07, 2010 at 15:14 UTC |