Perl STDOUT重定向到管道,调用sleep()后没有输出

时间:2014-02-10 15:41:23

标签: perl pipe stdout sleep tee

我在使用Windows上的Perl(ActivePerl和Strawberry)时遇到问题,将脚本STDOUT重定向到管道,并使用sleep()。试试这个:

perl -e "for (;;) { print 'Printing line ', $i++, \"\n\"; sleep(1); }"

这可以按预期工作。现在将它传递给Tee(或一些文件,相同的结果):

perl -e "for (;;) { print 'Printing line ', $i++, \"\n\"; sleep(1); }" | tee

根本没有输出,发球没什么。但是,perl脚本仍在运行,只有在脚本完成之前STDOUT上没有任何内容,然后所有输出都被转储到tee。但是,如果STDOUT缓冲区填充脚本可能会挂起。

现在,如果你删除了sleep(call),那么管道就会按预期运行!发生了什么事?

我找到了解决方法;使用$ | = 1禁用STDOUT缓冲会使管道在使用睡眠时工作,但是......为什么?任何人都可以解释并提供更好的解决方案吗?

1 个答案:

答案 0 :(得分:4)

你正在遭受缓冲。将$| = 1;添加到unbuffer STDOUT。

默认情况下,除STDERR之外的所有文件句柄都是缓冲的,但是当连接到终端时,STDOUT使用最小形式的缓冲(由换行符刷新)。通过用终端代替管道,恢复正常缓冲。

删除sleep电话不会改变任何事情,除非加快速度。而不是花费几分钟来填充缓冲区,它需要几毫秒。无论有没有,输出仍然以4k或8k块写入(取决于您的Perl版本)。