32

我在 Perl 中有以下两行:

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

问题是在 Perl 脚本暂停输入之前打印行没有被执行。也就是说,Perl 脚本似乎无缘无故地无限期停止。我猜输出以某种方式被缓冲(这就是我放入 \n 的原因,但这似乎没有帮助)。

4

5 回答 5

46

默认情况下,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 immediately and after every print.
$| = 1;
于 2015-11-19T19:30:17.493 回答
15

有几种方法可以打开自动刷新:

$|++;

在开头,或者也有一个BEGIN块:

BEGIN{ $| = 1; }

但是,您的配置似乎有些不寻常,因为通常最后的 a\n会触发刷新(至少是终端)。

于 2015-11-19T19:26:35.280 回答
3

对于那些不想像保姆一样称呼flush()追随者的人,因为它可能在 a或其他东西中,而您只是希望自己不受缓冲,然后只需将其放在 perl 脚本的顶部即可:printloopprint

STDOUT->autoflush(1);

此后,无需调用flush()after print

于 2019-11-03T15:20:40.960 回答
2
use IO::Handle;
STDOUT->flush();
于 2018-09-16T19:46:36.763 回答
1

是的。我在我的 util.pl 文件中为此创建了一个子例程,该文件在我require所有的 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()
}

于 2019-09-09T16:33:51.280 回答