Можете ли вы форсировать вывод в Perl?

У меня есть следующие две строки в Perl:

print "Warning: this will overwrite existing files.  Continue? [y/N]: \n";
my $input = <STDIN>;

Проблема в том, что строка печати не выполняется до того, как скрипт perl приостановит ввод. То есть сценарий perl просто останавливается на неопределенный срок без видимой причины. Я предполагаю, что вывод как-то буферизуется (именно поэтому я вставил \ n, но это, похоже, не помогает). Я довольно новичок в Perl, поэтому я буду признателен за любые советы, как обойти эту проблему.

3 ответа

Решение

По умолчанию, STDOUT буферизуется строкой (сбрасывается LF) при подключении к терминалу, и буферизуется блоком (сбрасывается при заполнении буфера) при подключении к чему-либо, кроме терминала. Более того, <STDIN> сбрасывает STDOUT, когда он подключен к терминалу.

Это означает

  • STDOUT не подключен к терминалу,
  • вы не печатаете на STDOUT, или
  • STDOUT был перепутан с.

print печатает в настоящее время selected дескриптор, когда дескриптор не предоставлен, поэтому будет работать следующее независимо от того, что из вышеприведенного верно

# Execute after the print.
# Flush the currently selected handle.
# Needs "use IO::Handle;" in older versions of Perl.
select()->flush();

или же

# Execute anytime before the <STDIN>.
# Causes the currently selected handle to be flushed after every print.
$| = 1;

Есть несколько способов включить автозапуск:

$|++;

в начале, или также с BEGIN блок:

BEGIN{ $| = 1; }

Тем не менее, это кажется чем-то необычным в вашей конфигурации, потому что обычно \n в конце запускается промывка (по крайней мере, терминала).

Тем, кто не хочет звонить flush() после каждого print как няня, потому что это может быть в loop или что-то в этом роде, и вы просто хотите, чтобы print чтобы быть небуферизованным, просто поместите это в верхнюю часть вашего perl-скрипта:

STDOUT->autoflush(1);

После этого звонить не нужно flush() после print.

use IO::Handle;
STDOUT->flush();

Да. Я сделал для этого подпрограмму в моем файле util.pl, которыйrequired во всех моих программах на Perl.

###########################################################################
# In: File handle to flush.
# Out: blank if no error,, otherwise an error message. No error messages at this time.
# Usage: flushfile($ERRFILE);
# Write any file contents to disk without closing file. Use at debugger prompt
# or in program.
sub flushfile
{my($OUTFILE)=@_;
my $s='';

my $procname=(caller(0))[3]; # Get this subroutine's name.

my $old_fh = select($OUTFILE);
$| = 1;
select($old_fh);

return $s; # flushfile()
}

Другие вопросы по тегам