我在使用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缓冲会使管道在使用睡眠时工作,但是......为什么?任何人都可以解释并提供更好的解决方案吗?
答案 0 :(得分:4)
你正在遭受缓冲。将$| = 1;
添加到unbuffer STDOUT。
默认情况下,除STDERR之外的所有文件句柄都是缓冲的,但是当连接到终端时,STDOUT使用最小形式的缓冲(由换行符刷新)。通过用终端代替管道,恢复正常缓冲。
删除sleep
电话不会改变任何事情,除非加快速度。而不是花费几分钟来填充缓冲区,它需要几毫秒。无论有没有,输出仍然以4k或8k块写入(取决于您的Perl版本)。