【问题标题】:Line buffered reading in PerlPerl 中的行缓冲读取
【发布时间】:2014-02-22 15:55:36
【问题描述】:

我有一个 perl 脚本,比如“process_output.pl”,它在以下上下文中使用:

long_running_command | “process_output.pl”

process_output 脚本需要类似于 unix “tee”命令,它在生成时将“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"

关于如何进一步进行的任何指示。

谢谢 乙

【问题讨论】:

    标签: perl unix


    【解决方案1】:

    这更有可能是第一个进程的输出被缓冲的问题,而不是脚本的输入。最简单的解决方案是尝试使用unbuffer 命令(我相信它是expect 包的一部分),类似于

    unbuffer long_running_command | "process_output.pl"
    

    unbuffer 命令将禁用当输出定向到非交互位置时正常发生的缓冲。

    【讨论】:

      【解决方案2】:

      这将是long_running_processing 的输出处理。它很可能正在使用stdio - 它会在输出之前查看输出文件描述符连接到什么。如果它是终端(tty),那么它通常会基于行输出,但在上述情况下 - 它会注意到它正在写入管道,因此会将输出缓冲成更大的块。

      您可以通过使用来控制自己进程中的缓冲,正如您所展示的那样

      select(STDOUT); $| =1;
      

      这意味着您的进程打印到 STDIO 的内容没有缓冲 - 对输入执行此操作没有任何意义,因为您可以控制缓冲完成的程度 - 如果您使用 sysread(),那么您正在阅读无缓冲的内容,如果您使用像 <$fh> 这样的构造,然后 perl 将等待,直到它有一个“整行”(它实际上读取到下一个输入行分隔符(在变量 $/ 中定义,默认情况下是换行符)),然后将数据返回到你。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-23
        • 2012-03-27
        • 1970-01-01
        • 2016-06-17
        • 2013-12-14
        • 1970-01-01
        • 2011-07-11
        相关资源
        最近更新 更多