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
In reply to "tee"ing my own stdout/stderr by conrad
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |