Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Suppress/Reactivate STDERR

by saintmike (Vicar)
on Dec 15, 2006 at 23:26 UTC ( [id://590153]=perlquestion: print w/replies, xml ) Need Help??

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... :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://590153]
Approved by Joost
Front-paged by bart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (9)
As of 2024-03-28 18:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found