【问题标题】:How can I suppress STDOUT temporarily in a Perl program?如何在 Perl 程序中暂时抑制 STDOUT?
【发布时间】:2009-09-04 00:08:09
【问题描述】:

有没有简单的方法告诉 perl“现在忽略所有打印的内容”?

我必须在外部 Perl 模块中调用一个过程,但该过程会打印很多不必要的信息(全部通过标准 print)。

我知道 select 可以用来以某种方式重定向它,但是阅读 perldoc 上的内容我不太明智。

编辑:我很快就找到了答案,但我会添加一个示例以使其更清楚(但我猜并不多)

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 和 TectoMT::Document 是那些外部模块

【问题讨论】:

  • 试试这个:打开标准输出,">/dev/null";不知道会发生什么...
  • 你如何称呼这些模块?你能提供一些代码或一些例子吗?
  • 彼得:通过标准电话:) 我会添加一个具体的例子,我很快找到了答案。我会将其发布为我自己问题的答案。

标签: perl filehandle


【解决方案1】:

我自己的回答:

use IO::Null;

print "does print.";

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

print "does not print.";

select($oldfh);

print "does print.";

【讨论】:

  • 这基本上是我的做法。
  • 这不适用于重定向使用system 调用的子进程的输出。
  • 你不应该在my $null = IO::Null 之后有一个->new 吗?它似乎工作得很好,但我不明白如何......
【解决方案2】:

我意识到这个问题已经得到解答,但我认为值得了解另一种方法。特别是如果某些事情一心想要打印到STDOUT...

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

密钥位是local *STDOUT。它将普通的STDOUT 替换为您选择的文件句柄,但仅适用于包含local 的块的范围。

【讨论】:

  • 这不适用于重定向使用system 调用的子进程的输出。
【解决方案3】:

参考这里和其他线程上的一些答案,我想出了这个;

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

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

"silently()" 接受一个仿函数并在 stdout 重定向的情况下运行它:

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;
}

【讨论】:

  • (感谢反馈 - Perl 新手)
【解决方案4】:
open my $saveout, ">&STDOUT";
open STDOUT, '>', "/dev/null";

(do your other stuff here)

open STDOUT, ">&", $saveout;

【讨论】:

  • 这个问题是我希望代码是多平台的,并不是所有系统都有/dev/null。幸运的是,有 IO::Null 来救我。
  • 您可能想在问题中提及该要求
  • IO:Null 不影响外部调用程序。但是您可以对受支持的系统使用上述方法(perl 可以检测操作系统),对不受支持的系统使用 IO:Null。您可以通过自己的功能覆盖它,该功能将自动选择正确的方法。注意,不仅 STDOUT 有问题,STDERR 也有同样的问题,那么你应该重定向两个流。
【解决方案5】:

如果您只想使用标准库中的模块,File::Spec 具有devnull() 函数。它返回一个代表空设备的字符串(*nix 上的"/dev/null"),您可能可以使用open() 打开它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 2011-09-07
    • 2012-11-15
    • 1970-01-01
    • 2015-11-11
    相关资源
    最近更新 更多