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

This must be a FAQ but I've yet to find the FQ. A function in a module which will remain nameless in order to protect the guilty spews out loads of stuff on STDOUT which I want to send to /dev/null. What I do not want to to do is forgo the ability to have a Perl script send useful stuff to STDOUT before and after the function call, so it would be nice if the function could be bracketed as follows:
$old_stdout = STDOUT; open STDOUT '> /dev/null'; $results = sub_with_logorrhea(); close STDOUT; open STDOUT $old_stdout;
but I'm buggered if I can find out how to do it properly. Clearly it is a matter of advancing senility, for which I apologize and beg your indulgence.

Replies are listed 'Best First'.
Re: Divert STDOUT temporarily
by tybalt89 (Monsignor) on Apr 27, 2020 at 17:45 UTC
    #!/usr/bin/perl use strict; # use warnings; print "one\n"; do { local *STDOUT; open STDOUT, '>', '/dev/null' or die; print "two\n +"; }; print "three\n";
      do { local *STDOUT; open STDOUT, '>', '/dev/null' or die; print "two\n +"; };

      You don't need a do{} block when just a bare block will do:

      { local *STDOUT; open STDOUT, '>', '/dev/null' or die; print "two\n"; +}

      Many thanks.

      Initial response is "Doh!"

      Second response: I knew I was becoming senile.

Re: Divert STDOUT temporarily
by davido (Cardinal) on Apr 27, 2020 at 19:15 UTC

    The documentation for open provides an example of duplicating and restoring filehandles:

    #!/usr/bin/perl open(my $oldout, ">&STDOUT") or die "Can't dup STDOUT: $!"; open(OLDERR, ">&", \*STDERR) or die "Can't dup STDERR: $!"; open(STDOUT, '>', "foo.out") or die "Can't redirect STDOUT: $!"; open(STDERR, ">&STDOUT") or die "Can't dup STDOUT: $!"; select STDERR; $| = 1; # make unbuffered select STDOUT; $| = 1; # make unbuffered print STDOUT "stdout 1\n"; # this works for print STDERR "stderr 1\n"; # subprocesses too open(STDOUT, ">&", $oldout) or die "Can't dup \$oldout: $!"; open(STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!"; print STDOUT "stdout 2\n"; print STDERR "stderr 2\n";


Re: Divert STDOUT temporarily
by AnomalousMonk (Archbishop) on Apr 27, 2020 at 18:11 UTC

    If output is not going to an explicit filehandle but to the default filehandle (which happens at that moment to be STDOUT), then select may be of interest.

    Give a man a fish:  <%-{-{-{-<

Re: Divert STDOUT temporarily
by haukex (Archbishop) on Apr 27, 2020 at 20:17 UTC

    IMHO the best way is Capture::Tiny's capture_stdout, or capture if you want to grab STDERR as well.

Re: Divert STDOUT temporarily
by roboticus (Chancellor) on Apr 27, 2020 at 17:53 UTC


    For the FAQs, try perldoc perlfaq at the command prompt, it'll show you the overview of the FAQ lists, and show you the category of content in the various pages of FAQs, like:

    perlfaq1 - General Questions About Perl perlfaq2 - Obtaining and Learning about Perl perlfaq3 - Programming Tools perlfaq4 - Data Manipulation perlfaq5 - Files and Formats perlfaq6 - Regular Expressions perlfaq7 - General Perl Language Issues perlfaq8 - System Interaction perlfaq9 - Web, Email and Networking

    So for questions related to regular expressions, you'd check perldoc perlfaq6.


    When your only tool is a hammer, all problems look like your thumb.

      There's also the perldoc -q switch, which will cause a FAQ keyword search.

      Give a man a fish:  <%-{-{-{-<

Re: Divert STDOUT temporarily
by bliako (Monsignor) on Apr 27, 2020 at 22:57 UTC

    If you want even finer control over who prints, what gets printed and how, this may be of interest: Override printing to STDOUT/ERR. The bottomline is that you can "intercept" all calls to writing to STDOUT, check who the caller is and filter.

    bw, bliako