Избавление от буферизации ruby ​​stdin/stdout

Я пытаюсь написать ruby ​​ script для фильтрации вывода хвостатого файла (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 журнал, я вижу много строк, написанных за секунду.

Ответ 1

Если вы имеете дело с файлами, вы, вероятно, захотите IO # fsync, в котором говорится:

Немедленно записывает все буферизованные данные в ios на диск. Обратите внимание, что fsync отличается от использования IO # sync =. Последнее гарантирует, что данные будут удалены из буферов Rubys, но не гарантирует, что базовая операционная система фактически записывает их на диск.

Если вы имеете дело со стандартным вводом и выводом, вы также можете попробовать io/console, чтобы увидеть, использует ли IO:: console # ioflush дает вам поведение, в котором вы нуждаетесь. В документации указано:

Сбрасывает входные и выходные буферы в ядре. Для использования этого метода необходимо использовать "io/console".

В качестве примера рассмотрим:

require 'io/console'

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