Dear monks,

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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.