2014-02-22 84 views
2

我有一个Perl脚本,说“process_output.pl”这是在下列情况下使用:行缓冲读取在Perl

long_running_command | “process_output.pl”

的process_output脚本,需要像Unix的“三通”命令,因为它得到生成的转储“long_running_command”到终端的输出,并且除了捕捉输出到文本文件,并且在“long_running_command”结尾处,以文本文件作为输入分叉另一个进程。

我目前看到的行为是,“long_running_command”的输出只有在完成而不是在生成时转储输出时才会转储到终端。我需要做一些特别的事情来解决这个问题吗?

基于我在其他几个stackexchange帖子的阅读,我试图在 “process_output.pl” 下面,没有太大的帮助:

  1. select(STDOUT); $| =1;
  2. select(STDIN); $| =1; # Not sure even if this is needed
  3. use FileHandle; STDOUT->autoflush(1);
  4. stdbuf -oL -eL long_running_command | "process_output.pl"

有关如何继续的任何指示 进一步。

感谢 AB

回答

4

这很可能是与第一个进程的输出问题被缓冲,而不是你的脚本的输入。最简单的解决办法是使用unbuffer命令(我相信这是expect包的一部分)的尝试,像

unbuffer long_running_command | "process_output.pl" 

unbuffer命令将禁用,通常发生在输出定向到非交互的缓冲地点。

1

这将是long_running_processing的输出处理。它很可能会使用stdio - 它会在输出之前查看输出文件描述符所连接的内容。如果它是一个终端(tty),那么它通常会输出基于行的数据,但在上面的例子中 - 它会注意到它正在写入一个管道,因此会将输出缓冲到较大的块中。

您可以通过使用控制缓冲在自己的过程中,你表现出

select(STDOUT); $| =1; 

这意味着东西,你的程序打印到STDIO,没有缓冲的 - 它没有任何意义这样的输入,因为你控制了多少缓冲 - 如果你使用sysread(),那么你正在读取无缓冲的,如果你使用像<$fh>这样的结构,那么perl将等待,直到它有一个“整行”(它实际上读取到下一个输入行分隔符在变量$/中定义,默认情况下是换行符)),然后它将数据返回给您。

unbuffer可用于“禁用”输出缓冲,它实际上所做的是使输出过程认为它正在与tty(通过使用伪tty)通信,因此输出过程不会缓冲。