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

After suppressing STDERR for a system() command, I can't seem to reactivate it afterwards, for subsequent system() commands. Here's the code:
my @cmd = ("/bin/ls", "/doesntexist"); use vars qw(*OLDERR); open OLDERR, ">&STDERR"; open STDERR, ">/dev/null"; # STDERR suppressed system(@cmd); *STDERR = *OLDERR; print STDERR "stderr is open\n"; # STDERR should be open - but isn't system(@cmd);
Both system() commands produce an error message on STDERR, but the first one gets suppressed since STDERR points to nowhere land. However, after restoring STDERR, I would expect the 2nd system() to actually print the error message. Alas, what I get is this:
stderr is open
which means that the print STDERR works ok, but the system()'s STDERR channel is still blocked. Is this a bug?

Replies are listed 'Best First'.
Re: Suppress/Reactivate STDERR
by ikegami (Patriarch) on Dec 15, 2006 at 23:55 UTC

    STDERR is not necessarily the same thing as file descriptor 2 (and it isn't after you do *STDERR = *OLDERR;). For commands executed by system, file descriptor 2 is stderr. They have no knowledge of the file descriptor associated with your program's STDERR variable.

    Replace
    *STDERR = *OLDERR;
    with
    open STDERR, ">&OLDERR";

    Update: s/3/2/g. Thanks nobull.

      STDERR is not necessarily the same thing as file descriptor 3
      s/3/2/

      In recent Perl there's no need to use package variables for file handles to achieve this.

      open my $olderr, '>&', \*STDERR or die $!; #... open STDERR, '>&', $olderr or die $!;

        Re: 2 vs 3 -- Thanks, typo!

        Re: lexical file handles -- True. I just went along with the code that was already there. Lexicals can be used for file handles since Perl 5.6.0.

Re: Suppress/Reactivate STDERR
by almut (Canon) on Dec 15, 2006 at 23:54 UTC

    In case you just want to get the code working, you can reopen STDERR

    open(STDERR, ">&OLDERR"); # instead of # *STDERR = *OLDERR;

    If however, you'd like to understand why the glob assignment suffices for the print but not for the subprocess' output, you'll have to wait for wiser heads than mine to explain... :)