2015-09-20 109 views
3

我正在调试一个守护进程,我试图使用print语句将信息输出到终端。我的代码的要点是:为什么我的perl守护进程不能打印?

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Readonly; 

Readonly my $TIMEOUT => ...; 

... 

while (1) { 

    print "DEBUG INFO"; 

    ... 

    sleep $TIMEOUT; 
} 

但是,没有输出它打印到我的终端。为什么是这样?

+0

守护进程的STDOUT通常有目的地指向终端以外的某个地方。你是如何守护程序的? – ikegami

回答

7

摘要:

使用$| = 1或换行,"\n"添加到打印。

说明:

这不是打印到终端的原因是因为Perl正在缓冲对效率的输出。一旦打印缓冲区被填满,它将被刷新并且输出将出现在您的终端中。您可能希望强制冲洗缓冲区,因为根据您的输出长度,您可能会等待相当长的时间!

主要有两种方法来刷新缓冲区:

1)当你打印到你的终端,那么你的文件句柄是最有可能STDOUT。把手附连到终端的任何文件都默认在行缓冲模式,我们可以刷新缓冲区,并通过添加一个新行字符到您print语句强制输出:

while (1) { 
    print "DEBUG INFO\n"; 
    ... 
    sleep $TIMEOUT; 
} 

2)第二种方法是使用$|,当设置为非零时,使当前文件句柄(默认为STDOUT或最后为select ed)并立即强制刷新缓冲区。因此,以下也将迫使调试信息打印:

$| = 1; 
while (1) { 
    print "DEBUG INFO"; 
    ... 
    sleep $TIMEOUT; 
} 

如果使用语法,如这是混乱的,那么你可能要考虑:

use IO::Handle; 
STDOUT->autoflush(1); 

while (1) { 
    print "DEBUG INFO"; 
    ... 
    sleep $TIMEOUT; 
} 

在许多代码示例,其中直接冲洗的缓冲区是必需的,你可能会看到$|++用于使文件句柄变热并立即刷新缓冲区,并且--$|使文件句柄冷却并关闭自动刷新。看到这两个答案,了解更多详情:

如果您有兴趣学习更多关于Perl的缓冲区,那么我建议阅读Suffering from Buffering,这给了伟大的洞察为什么我们有缓冲并解释如何打开和关闭它。

相关问题