How can I suppress STDOUT temporarily in a Perl program?

空扰寡人 提交于 2019-11-30 14:20:17

My own answer:

use IO::Null;

print "does print.";

my $null = IO::Null;
my $oldfh = select($null); 

print "does not print.";

select($oldfh);

print "does print.";

I realise that this has been answered, but I think it's worth knowing about an alternative method of doing this. Particularly if something is hell-bent on printing to STDOUT

# Store anything written to STDOUT in a string.
my $str;
open my $fh, '>', \$str;
{
  local *STDOUT = $fh;
  code_that_prints_to_stdout();
}

The key bit is local *STDOUT. It replaces the normal STDOUT with a filehandle of your choosing, but only for the scope of the block containing the local.

Referring to some answers here and on other threads, I came up with this;

use strict;
use warnings;
use File::Spec;

sub my_functor { system("some_noisy_command.exe", "--option1", "--option2"); }
silently(\&my_functor);

Where "silently()" takes a functor and runs it with stdout redirected:

sub silently($) {
    #Turn off STDOUT
    open my $saveout, ">&STDOUT";
    open STDOUT, '>', File::Spec->devnull();

    #Run passed function
    my $func = $_[0];
    $func->();

    #Restore STDOUT
    open STDOUT, ">&", $saveout;
}
open my $saveout, ">&STDOUT";
open STDOUT, '>', "/dev/null";

(do your other stuff here)

open STDOUT, ">&", $saveout;

If you want to use only modules in the standard library, File::Spec has the devnull() function. It returns a string representing the null device ("/dev/null" on *nix) that you can presumably open with open().

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!