Можете ли вы форсировать вывод в 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
печатает в настоящее время select
ed дескриптор, когда дескриптор не предоставлен, поэтому будет работать следующее независимо от того, что из вышеприведенного верно
# 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
.
Да. Я сделал для этого подпрограмму в моем файле 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)=@_;
my $s='';
my $procname=(caller(0))[3]; # Get this subroutine's name.
my $old_fh = select($OUTFILE);
$| = 1;
select($old_fh);
return $s; # flushfile()
}