Ectaris has asked for the wisdom of the Perl Monks concerning the following question:

I was looking to do the same thing for STDERR and the answer I came up with seemed a little simpler:

open( logFile, ">log.txt"); *STDERR = *logFile;

Any reason why this shouldn't be used?

Replies are listed 'Best First'.
Re: how do i redirect STDOUT, STDIN, or STDERR to a FILE? (*A=*B sucks)
by tye (Sage) on Dec 28, 2011 at 20:24 UTC

    Yes, actually there are quite a few good reasons to not do that.

    open( LOG, ">>", "log.txt" ) or die "Can't' write to log.txt: $!\n"; *STDOUT= *LOG; print "Yay! This goes to log.txt! Success!\n"; # Reason 1: system("echo Boo, this goes to the old STDOUT"); # Reason 2: close STDOUT; print LOG "Boo, this goes nowhere but I didn't close *LOG!\n"; # Reason 3: open STDOUT, '>>', 'newlog.txt' or die "Can't write to newlog.txt: $!\n"; system("echo Boo, this still goes to old STDOUT despite reopening");

    *STDOUT = *LOG makes STDOUT and LOG share the same file handle in a way that is problematic to sane lifespan control. It also hides the old file handle for STDOUT away in a dark place where it will still get used by all manner of things that correctly know that FD 1 is how you send "standard output". And since FD 1 is kept open by this hidden-away, still-open file handle, open's careful work to try to make "open STDOUT" and "open STDERR" work correctly (ie. to have the first impact FD 1 and the second impact FD 2) is forever thwarted.

    Just don't manipulate file handles by local()izing and/or overwriting perl globs. Lots of pain to be had there. And this goes doubly when dealing with the STD* file handles.

    - tye        

Re: how do i redirect STDOUT, STDIN, or STDERR to a FILE?
by ikegami (Patriarch) on Dec 28, 2011 at 17:45 UTC
    Nope, but there are limitations to it. Anything that uses file descriptor 2 (e.g. system) to mean STDERR won't see your change. Better:
    open(STDERR, ">log.txt")
Re: how do i redirect STDOUT, STDIN, or STDERR to a FILE?
by mr.nick (Chaplain) on Dec 28, 2011 at 17:48 UTC
    open STDERR,">","stderr.log" or die $!; open STDOUT,">","stdout.log" or die $!;
    It's a bit more clear and obvious. Redirecting STDIN *to* a file makes no sense, but I suppose you could do:
    open STDIN,"<","stdin.txt" or die $!; print while <>;
    But I'm not sure what the purpose of that would be.

    mr.nick ...

Re: how do i redirect STDOUT, STDIN, or STDERR to a FILE?
by NetWallah (Canon) on Dec 28, 2011 at 18:35 UTC
    Here is a small module I wrote years ago.. to use:
    STDERR_REDIRECTOR::capture(); # Do stuff that writes to STDERR|; STDERR_REDIRECTOR::release(); STDERR_REDIRECTOR::showcapture();

                "Battle not with trolls, lest ye become a troll; and if you gaze into the Internet, the Internet gazes also into you."
            -Friedrich Nietzsche: A Dynamic Translation