Почему Perl разрешает чтение в реальном времени из дескриптора файла процесса, если я печатаю $_?

Я пишу программу на Perl, которая фиксирует вывод другой программы, и я заметил, что в цикле while <FILEHANDLE> (поэтому $_ содержит прочитанную строку) происходит следующее:

open XIN, "-|", "test_xsr"; # not getting in real time! FIX
while (<XIN>) {
    print ".";
}

отпечатки

....

после завершения программы во время

open XIN, "-|", "test_xsr"; # not getting in real time! FIX
while (<XIN>) {
    print $_;
}

отпечатки

1
2
3
done

в режиме реального времени, во время работы программы. (Пока я тестирую, программа всегда выдает этот результат.)

Почему возникает это несоответствие?
Можно ли обрабатывать выходные данные в режиме реального времени без printing$_?


person Nonny Moose    schedule 14.06.2017    source источник
comment
Я уверен, что должен быть канонический ответ, который говорит об этом, но я не могу его найти.   -  person Sobrique    schedule 14.06.2017
comment
Речь идет не о строковой буферизации дескриптора файла input. Дело в том, что строки, которые вы читаете из XIN, имеют в конце новые строки. Шокирует, я знаю. Итак, когда вы их печатаете, вывод очищается. Принимая во внимание, что если вы просто печатаете точки, вывод находится в буфере до тех пор, пока он не будет заполнен.   -  person Sinan Ünür    schedule 14.06.2017
comment
@SinanÜnür Спасибо, вы нашли решение моей проблемы.   -  person Nonny Moose    schedule 15.06.2017


Ответы (1)


По умолчанию, если STDOUT подключен к терминалу, STDOUT сбрасывается только при обнаружении новой строки или заполнении буфера. В вашем втором фрагменте есть новая строка, которая приводит к очистке буфера, но не в первом фрагменте.

Добавьте следующее после print, чтобы принудительно очистить вывод:

STDOUT->flush();

Добавьте следующее в свою программу, чтобы всегда сбрасывать после записи в STDOUT:

STDOUT->autoflush();

(Для их использования в старых версиях Perl требуется use IO::Handle qw( );.)

person ikegami    schedule 14.06.2017