我正在尝试编写一个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
日志,那么我会看到每秒写入多行。
答案 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