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

时间:2018-01-03 21:32:46

标签: perl

我编写了一个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";

它从不打印Past loop:它只是挂在输出的最后一行,我认为被调用的脚本会产生。

1 个答案:

答案 0 :(得分:3)

您需要在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

对于非xargs程序,无论如何关闭管道或者至少刷新它可能仍然是一个好主意,因为在某个级别的缓冲区中可能存在字节。