摆脱ruby stdin / stdout缓冲

时间:2014-10-12 19:47:15

标签: ruby stdout stdin

我正在尝试编写一个ruby脚本来过滤有尾文件(tail -f log.log | ./my_filter.rb)的输出。我相信我已经将stdin和stdout设置为同步读取,但我仍然看到我的输出以延迟批次出现,一次出现20行左右,而不是实时出现。

我可以使用以下代码重现问题:

#!/usr/bin/ruby     

$stdout.sync = true 
$stdin.sync = true  

ARGF.each do |line| 
  puts line         
end                 

我是否错过了消除缓冲的设置,或者沿着那些方向的东西?

编辑:澄清一下,如果我只是tail -f日志,那么我会看到每秒写入多行。

3 个答案:

答案 0 :(得分:4)

如果你正在处理文件,你可能需要IO#fsync,其中说:

  

立即将ios中的所有缓冲数据写入磁盘。请注意,fsync与使用IO#sync =不同。后者确保数据从Ruby的缓冲区中刷新,但不保证底层操作系统实际将其写入磁盘。

如果您只处理标准输入和输出,您可能还会尝试io/console来查看使用IO::console#ioflush是否为您提供了所需的行为。文档说:

  

刷新内核中的输入和输出缓冲区。   您必须要求'io / console'才能使用此方法。

举个例子,考虑一下:

require 'io/console'

ARGF.each do |line|
  $stdout.puts line
  $stdout.ioflush
end

答案 1 :(得分:1)

这是一个古老的问题,但是被接受的答案不能完全回答问题恕我直言。

您可以将$stdout.sync = true放在程序的开头,以将同步输出输出到stdout(如果需要,可以使用require 'io/console')。

答案 2 :(得分:0)

这个线程的标题包括标准输入和标准输出,所以添加到其他答案中,没有一个解决标准输入:

$stdin.iflush # Discard anything currently in $stdin's byte buffer