Bidirectional Communication
Although using open to connect
to another command over a pipe works reasonably well for
unidirectional communication, what about bidirectional communication?
The obvious approach doesn’t actually work:
open(PROG_TO_READ_AND_WRITE, "| some program |") # WRONG!
and if you forget to enable warnings, then you’ll miss out entirely on the diagnostic message:
Can't do bidirectional pipe at myprog line 3.
The open function doesn’t allow
this because it’s rather prone to deadlock unless you’re quite careful.
But if you’re determined, you can use the standard IPC::Open2 library module to attach two pipes to a subprocess’s
STDIN and STDOUT. There’s also an IPC::Open3 module for tridirectional I/O (allowing you to also catch
your child’s STDERR), but this
requires either an awkward select
loop or the somewhat more convenient IO::Select module. But then you’ll have to avoid Perl’s buffered
input operations like <>
(readline).
Here’s an example using open2:
use IPC::Open2;
local (*Reader, *Writer);
$pid = open2(\*Reader, \*Writer, "bc –l");
$sum = 2;
for (1 .. 5) {
print Writer "$sum * $sum\n";
chomp($sum = <Reader>);
}
close Writer;
close Reader;
waitpid($pid, 0);
print "sum is $sum\n";You can also autovivify lexical filehandles:
my ($fhread, $fhwrite); $pid = open2($fhread, $fhwrite, "cat –u –n");
The problem with this in general is that standard I/O buffering is really going to ruin your day. Even though your output filehandle is autoflushed (the library does this for you) ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access