Perl 将文本写入管道,读取结果永远不会完成

Perl 将文本写入管道,读取结果永远不会完成,perl,Perl,我编写了一个Perl程序,它打开一个管道到xargs,这样它就可以从输入中读取数据,并对每一行输入运行一个命令 我需要读取管道的输出 我使用open3,然后将输入写入输入文件句柄。然后一个循环从输出文件句柄中读取 但当它打印出我希望看到的最后一行时,它只是挂起,并没有完成这个过程 这是剧本的摘录 my $classNamesOutput = `classNamesInArchive $opt_archive`; my $pid = open3( \*CHILD_IN, \*CHILD_OUT,

我编写了一个Perl程序,它打开一个管道到
xargs
,这样它就可以从输入中读取数据,并对每一行输入运行一个命令

我需要读取管道的输出

我使用
open3
,然后将输入写入输入文件句柄。然后一个循环从输出文件句柄中读取

但当它打印出我希望看到的最后一行时,它只是挂起,并没有完成这个过程

这是剧本的摘录

my $classNamesOutput = `classNamesInArchive $opt_archive`;

my $pid = open3( \*CHILD_IN, \*CHILD_OUT, false, "xargs -n1 listJavaClassRefs -p $opt_archive -c" );
print "pid[" . $pid . "]\n";

print CHILD_IN $classNamesOutput;

my $output = '';
my $matchingArchiveNames = '';

while ( my $row = <CHILD_OUT> ) {
    chomp $row;
    print "row[" . $row . "]\n";

    if ( $onlyListingMatches == 1 && $row eq $opt_className ) {
        print $opt_archive;
        last;
    }

    if ( $onlyListingMatches == 0 ) {
        $output .= $row . "\n";
    }
}

print "Past loop.\n";
my$classNamesOutput=`classNamesInArchive$opt_archive`;
my$pid=open3(\*CHILD\u IN,\*CHILD\u OUT,false,“xargs-n1listjavaclassrefs-p$opt\u archive-c”);
打印“pid[”$pid.]\n”;
打印$classNamesOutput中的子单元;
我的$output='';
我的$matchingArchiveNames='';
while(my$row=){
咀嚼$row;
打印“行[”$row.]\n”;
if($onlyistingmatches==1&&$row eq$opt_className){
打印$opt_档案;
最后;
}
如果($onlyStingMatches==0){
$output.=$row.“\n”;
}
}
打印“过去循环。\n”;

它从不打印
过去的循环
:它只是挂起在我认为被调用脚本会生成的输出的最后一行。

在while循环之前,您需要关闭writer:

close CHILD_IN;
编辑:需要关闭xargs管道(但不是一般情况下)的原因是,xargs显然在输入完成之前不会启动任何进程。这可以通过运行
cat | xargs echo
看到:

cat | xargs echo
asdf
asd
faw
seas
eryawr
yawr
ya
ryhs
rhy
erh
< I press Ctrl-d here to terminate pipe >
asdf asd faw seas eryawr yawr ya ryhs rhy erh
cat | xargs回波
asdf
自闭症
一汽
海洋
埃里亚尔
雅尔
嗯
里斯
rhy
呃
<我在此处按Ctrl-d终止管道>
asdf asd faw seas eryawr yawr YAHS rhy erh

对于非xargs程序,关闭管道或至少刷新管道仍然是一个好主意,因为在某个级别上缓冲区中可能会有字节卡住。

您需要在while循环之前关闭写入程序:

close CHILD_IN;
编辑:需要关闭xargs管道(但不是一般情况下)的原因是,xargs显然在输入完成之前不会启动任何进程。这可以通过运行
cat | xargs echo
看到:

cat | xargs echo
asdf
asd
faw
seas
eryawr
yawr
ya
ryhs
rhy
erh
< I press Ctrl-d here to terminate pipe >
asdf asd faw seas eryawr yawr ya ryhs rhy erh
cat | xargs回波
asdf
自闭症
一汽
海洋
埃里亚尔
雅尔
嗯
里斯
rhy
呃
<我在此处按Ctrl-d终止管道>
asdf asd faw seas eryawr yawr YAHS rhy erh

对于非xargs程序,关闭管道或至少刷新管道仍然是一个好主意,因为缓冲区中可能会有某些级别的字节卡住。

请详细说明您的建议请详细说明您的建议我的编辑是否正确表示了您的问题?请不要对所有内容进行个性化设置。您从哪里获得的
open3
?您是否
使用了
您没有提到的任何模块?除了您所问的问题之外,您的程序还存在shell命令注入错误
“xargs-n1 listJavaClassRefs-p$opt_archive-c”
应该是
“xargs”、“-n1”、“listJavaClassRefs”、“-p”、$opt_archive、“-c”
。除了您询问的问题之外,您的程序还存在竞争条件。如果您想要双向通信,请避免使用
open3
(因为您需要开始使用IPC::Select,这会变得非常复杂)。请改用IPC::Run3或IPC::Run。@Borodin我不知道你说的“个性化”是什么意思。我从cpan得到了open3。我还能从哪里得到它?我的编辑是否正确地反映了您的问题?请不要对所有内容进行个性化设置。您从哪里获得的
open3
?您是否
使用了
您没有提到的任何模块?除了您所问的问题之外,您的程序还存在shell命令注入错误
“xargs-n1 listJavaClassRefs-p$opt_archive-c”
应该是
“xargs”、“-n1”、“listJavaClassRefs”、“-p”、$opt_archive、“-c”
。除了您询问的问题之外,您的程序还存在竞争条件。如果您想要双向通信,请避免使用
open3
(因为您需要开始使用IPC::Select,这会变得非常复杂)。请改用IPC::Run3或IPC::Run。@Borodin我不知道你说的“个性化”是什么意思。我从cpan得到了open3。我还能从哪里得到它?