我有一个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”中尝试了以下内容,没有太多帮助:
select(STDOUT); $| =1;
select(STDIN); $| =1; # Not sure even if this is needed
use FileHandle; STDOUT->autoflush(1);
stdbuf -oL -eL long_running_command | "process_output.pl"
关于如何进一步行动的任何指示。
由于 AB
答案 0 :(得分:4)
这更有可能是缓冲的第一个进程的输出的问题,而不是脚本的输入。最简单的解决方案是尝试使用unbuffer
命令(我相信它是expect
包的一部分),类似
unbuffer long_running_command | "process_output.pl"
unbuffer
命令将禁用当输出定向到非交互位置时正常发生的缓冲。
答案 1 :(得分:1)
这将是long_running_processing
的输出处理。很可能它正在使用stdio
- 它将查看输出文件描述符在输出之前连接的内容。如果它是一个终端(tty),那么它通常会输出基于行的,但在上面的情况下 - 它会注意到它正在写入管道,因此会将输出缓冲到更大的块中。
您可以使用,如您所示
,在您自己的过程中控制缓冲select(STDOUT); $| =1;
这意味着你的进程打印到STDIO的东西没有被缓冲 - 为输入做这个是没有意义的,因为你控制了多少缓冲 - 如果你使用sysread()
那么你正在读取无缓冲,如果你使用像<$fh>
这样的结构,那么perl会等到它有一个“整行”(它实际读取到下一个输入行分隔符(在变量$/
中定义,默认为换行符) )在它向你返回数据之前。
unbuffer
可以用来“禁用”输出缓冲,它实际上做的是让输出过程认为它正在与tty
通话(通过使用伪tty)所以输出过程没有缓冲。