How can I suppress STDOUT temporarily in a Perl program?
Asked Answered
T

5

8

Is there any easy way to tell perl "now ignore everything that is printed"?

I have to call a procedure in an external Perl module, but the procedure prints a lot of unnecessary information (all through standard print).

I know select can be used to redirect it somehow, but I am not too wise from reading perldoc on it.

edit: I found the answer sooner, but I will add an example to make it clearer (but not much I guess)

use TectoMT::Scenario;
use TectoMT::Document;

sub tagDocuments {
    my @documents = @_;

    my $scenario = TectoMT::Scenario->new({'blocks'=> [ qw(
            SCzechW_to_SCzechM::Sentence_segmentation 
            SCzechW_to_SCzechM::Tokenize  
            SCzechW_to_SCzechM::TagHajic
            SCzechM_to_SCzechN::Czech_named_ent_SVM_recognizer) ]});

    $scenario->apply_on_tmt_documents(@documents);
    return @documents;
}

TectoMT::Scenario and TectoMT::Document are those external modules

Tetracycline answered 4/9, 2009 at 0:8 Comment(3)
Try this: open STDOUT, ">/dev/null"; not sure whats going to happen...Pattern
How are you calling those modules? Can you provide some code or some example?Detritus
Peter: trough a standard call :) I will add a concrete example anyway, I found an answer sooner. I will post it as answer to my own question.Kilan
T
13

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.";
Tetracycline answered 4/9, 2009 at 0:29 Comment(3)
This is basically how I do it.Aricaarick
This doesn't work for redirecting the output of a subprocess called with system.Duomo
Shouldn't you have a ->new after my $null = IO::Null? It seems to work just fine as it is, but I don't understand how....Dannadannel
V
9

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.

Vitta answered 4/9, 2009 at 9:55 Comment(1)
This doesn't work for redirecting the output of a subprocess called with system.Duomo
L
7

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;
}
Lowe answered 28/3, 2013 at 16:33 Comment(1)
(Feedback appreciated - Perl novice)Lowe
S
2
open my $saveout, ">&STDOUT";
open STDOUT, '>', "/dev/null";

(do your other stuff here)

open STDOUT, ">&", $saveout;
Savoie answered 4/9, 2009 at 0:19 Comment(3)
problem with this is I want the code to be multiplatform and not all systems have /dev/null. Luckily, there is IO::Null to save me.Kilan
You might want to mention that requirement in the questionEveryman
IO:Null does not affect external called programs. but you can use method above for supported system (perl can detect OS), and IO:Null for unsupported. You can cover it by your own function that will automatically select properly method. Notice, not only STDOUT is problem, the same problem is with STDERR, then you should redirect both streams.Nebo
Y
2

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

Younglove answered 4/9, 2009 at 0:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.