Perl,禁用缓冲输入 [英] Perl, disable buffering input
问题描述
有一个文件:
:~$ cat fff
qwerty
asdf
qwerty
zxcvb
有一个脚本:
:~$ cat 1.pl
#!/usr/bin/perl
print <STDIN>
该命令按预期工作:
:~$ cat fff | perl -e 'system("./1.pl")'
qwerty
asdf
qwerty
zxcvb
但是这个命令不会按预期工作:第一个 <STDIN>读取所有数据,而不是一行.如何禁用 <STDIN> 的缓冲?
But this command will not work as expected: the first <STDIN> reads all the data, not a single line. How to disable buffering for <STDIN>?
:~$ cat fff | perl -e '$_ = <STDIN>; system("./1.pl")'
:~$
推荐答案
这里有两个 Perl 进程 - 第一个分配 $_ = <STDIN>
并调用 system
,第二个执行 print <STDIN>
There are two Perl processes here - the first that assigns $_ = <STDIN>
and calls system
, and the second that does print <STDIN>
虽然第一个进程只将流的第一行读入$_
,但在幕后,Perl 已用数据填充其缓冲区并将流留空
Although only the first line of the stream is read into $_
by the first process, behind the scenes Perl has filled its buffer with data and left the stream empty
这样做的目的是什么?想到做你要求的唯一方法是在第一个进程中将文件的all读入一个数组,然后删除第一行并将其余部分通过管道发送到第二个脚本
What is the purpose of this? The only way that comes to mind to do what you ask is to read all of the file into an array in the first process, and then remove the first line and send the rest in a pipe to the second script
所有这些似乎都没有必要,如果您能描述潜在的问题,我相信有更好的方法
All of this seems unnecessary, and I am sure there is a better method if you will describe the underlying problem
更新
既然你说你知道缓冲问题,那么这样做的方法是使用sysread
,它会从较低级别的管道中读取并避免缓冲
Since you say you are aware of the buffering problem, the way to do this is to use sysread
, which will read from the pipe at a lower level and avoid the buffering
这样的东西会起作用
cat fff | perl -e 'while (sysread(STDIN, $c, 1)) {$_ .= $c; last if $c eq "\n"} system("./1.pl")'
但我不喜欢推荐它,因为你所做的似乎很错误,我希望你能解释一下你的真正目标
But I don't like recommending it as what you are doing seems very wrong and I wish you would explain your real goal
这篇关于Perl,禁用缓冲输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!