将消息打印到屏幕和文件

时间:2016-05-11 13:22:04

标签: perl

我有在Windows中运行的perl脚本。在脚本中我调用另一个perl脚本。我正在尝试将这两个脚本打印到cmd窗口和文件中。这基本上就是我打电话的方式

    using IO::Tee
    open (my $file, '>>', "C:\\Logs\\logfile.txt") or die "couldn't open log file:  $!";
    me $tee = IO::Tee->new(\*STDOUT, $file);
    # doing some stuff 
    print $tee "log about what i just did";
    # do more stuff 
    print $tee "more logs";
    print $tee `c:\\secondScript.pl arg1`;
    print $tee "done with script";

第二个脚本基本上是

    # do stuff
    print "script 2 log about stuff";
    # do more stuff
    print "script 2 log about more stuff";
    print "script 2 done";

这确实可以获得屏幕和文件的所有内容。但是,在脚本2完成之前,我没有看到“脚本2记录关于东西”,“脚本2记录更多东西”和“脚本2完成”。我想在打印到达后立即看到所有流到屏幕和文件。

1 个答案:

答案 0 :(得分:2)

当输出到达终端时,打印到STDOUT通常是行缓冲(以加快速度),否则块缓冲(例如,当将输出重定向到文件时)。
您可以将其视为首先将任何打印的内容放入缓冲区(通常为4096字节大),并且只有当缓冲区已满时(即打印了4096个字符)时,它才会输出到屏幕上。

行缓冲表示仅在找到\n(或缓冲区已耗尽)后才会在屏幕上显示输出。您的第二个脚本中没有\n,因此在a)\n到来之前,b)缓冲区已满,或c)脚本结束时,不会显示输出。

阻止缓冲表示仅在缓冲区已满时显示输出。 \n这里不会影响这个(除了计算为一个字符)。

为避免缓冲,有一个名为$|魔术变量。从docs(向下滚动到$|部分):

  

如果设置为非零,则立即强制刷新并在每次写入或之后   在当前选定的输出通道上打印。

因此,您可以将"\n"附加到您的打印语句中,或者 - 更好 - 在第二个脚本之上设置$| = 1;(仅限一次,而不是每个print)。这将减慢第二个脚本的输出(理论上),但对于几行,它将没有任何区别。