Reputation: 15225
I've written a Perl program that opens a pipe to xargs
so that it will read from the input and run a command with each row of input.
I need to read the output from that pipe.
I use open3
and then write the input to the input file handle. Then a loop reads from the output filehandle.
But when it prints the last line that I expect to see, it just hangs and doesn't complete the process.
Here's an excerpt from the script
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";
It never prints Past loop
: it just hangs on the last line of output that I think the called script would have produced.
Upvotes: 0
Views: 167
Reputation: 820
You need to close the writer before the while loop:
close CHILD_IN;
Edit: The reason you need to close the pipe for xargs (but not in general) is that xargs apparently does not launch any processes until the input in finished. This can be seen by running 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
For non-xargs programs it might still be a good idea anyways to close the pipe, or at least flush it, since there might be bytes stuck in a buffer at some level.
Upvotes: 4