Perl - 从外部进程直接输出到标准输出(避免缓冲)

Posted

技术标签:

【中文标题】Perl - 从外部进程直接输出到标准输出(避免缓冲)【英文标题】:Perl - output from external process directly to stdout (avoid buffering) 【发布时间】:2012-07-12 16:13:06 【问题描述】:

我有一个 Perl 脚本,它必须包装一个 php 脚本,该脚本会产生大量输出,并且需要大约半小时才能运行。

此刻我正在全力以赴:

print `$command`;

这在调用 PHP 脚本的意义上是有效的,它完成了它的工作,但是,直到 PHP 脚本在半小时后完成,Perl 才会呈现输出。

有没有一种方法可以让 perl 在收到 PHP 的输出后立即打印它?

【问题讨论】:

【参考方案1】:

问题是 Perl 在 PHP 脚本终止之前不会完成读取,只有当它完成读取时才会写入。反引号操作符会阻塞,直到子进程退出,并且隐式地进行读/写循环没有什么魔力。

所以你需要写一个。尝试管道打开:

open my $fh, '-|', $command or die 'Unable to open';
while (<$fh>) 
    print;

close $fh;

这应该在 PHP 脚本写入时读取每一行,并立即输出。如果 PHP 脚本没有在方便的行中输出,并且您想使用单个字符执行此操作,则需要考虑使用 read 从文件句柄中获取数据,并禁用输出缓冲 ($| = 1)用于编写它的标准输出。

另见http://perldoc.perl.org/perlipc.html#Using-open()-for-IPC

【讨论】:

【参考方案2】:

你真的在做print `$command`吗?

如果您只运行命令而不捕获其任何输出,只需使用system $command。它将直接写入标准输出而不通过 Perl。

【讨论】:

是的,我确实在按照我在问题中所说的那样做,是的,在这种情况下这样做是明智的。感谢这个解决方案 - 非常简单,而且效果很好!【参考方案3】:

您可能想调查Capture::Tiny。 IIRC 这样的事情应该可以工作:

use strict;
use warnings;

use Capture::Tiny qw/tee/;

my ($stdout, $stderr, @result) = tee  system $command ;

实际上,只使用system 可能就足够了,YMMV。

【讨论】:

以上是关于Perl - 从外部进程直接输出到标准输出(避免缓冲)的主要内容,如果未能解决你的问题,请参考以下文章

Perl基础命令---文件句柄基础

如何将命令发送到在 perl 的非标准端口上运行的 telnet

什么是spool系统,什么是预输入,什么是缓输出?

C语言编程: CreateProcess标准输出重定向到文件

从 Perl 中的输出记录

使用带有标准输入和标准输出重定向的 2 进程管道时如何避免标准输入上的重复输入