Вы можете принудительно вывести поток в perl

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

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

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

Ответ 1

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

Это значит

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

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

# 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;

Ответ 2

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

$|++;

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

BEGIN{ $| = 1; }

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

Ответ 3

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

Ответ 4

Да. Я сделал подпрограмму для этого в моем файле util.pl, который require d во всех моих программах 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)[email protected]_;
my $s='';

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

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

return $s; # flushfile()
}