use IPC::Open2;
# with named filehandles
$pid = open2(\*RDR, \*WTR, $cmd_with_args);
$pid = open2(\*RDR, \*WTR, $cmd, "
arg1
", "
arg2
", ...);
# with object-oriented handles
use FileHandle;
my($rdr, $wtr) = (FileHandle->new, FileHandle->new);
$pid = open2($rdr, $wtr, $cmd_with_args);
The
open2()
function forks a child process to execute the
specified command. The first two arguments represent filehandles, one
way or another. They can be FileHandle objects, or they can be
references to typeglobs, which can either be explicitly named as above,
or generated by the Symbol package, as in the example below. Whichever
you choose, they represent handles through which your program can read
from the command's standard output and write to the command's standard
input, respectively.
open2()
differs from Perl's built-in
open
function in that it allows your program to communicate in
both directions with the child process.
open2()
returns the process ID of the child process. On failure it
reports a fatal error.
Here's a simple use of
open2()
by which you can give the program
user interactive access to the
bc
(1) command. (
bc
is an
arbitrary-precision arithmetic package.) In this case we use the Symbol
module to produce "anonymous" symbols:
use IPC::Open2;
use Symbol;
$WTR = gensym(); # get a reference to a typeglob
$RDR = gensym(); # and another one
$pid = open2($RDR, $WTR, 'bc');
while (<STDIN>) { # read commands from user
print $WTR $_; # write a command to bc(1)
$line = <$RDR>; # read the output of bc(1)
print STDOUT "$line"; # send the output to the user
}
open2()
establishes unbuffered output for
$WTR
. However,
it cannot control buffering of output from the designated command.
Therefore, be sure to heed the following warning.
WARNING:
It is extremely easy for your program to hang while waiting
to read the next line of output from the command. In the example just
shown,
bc
is known to read and write one line at a time, so it is
safe. But utilities like
sort
(1) that read their entire input
stream before offering any output will cause a deadlock when used in the
manner we have illustrated. You might do something like this instead:
$pid = open2($RDR, $WTR, 'sort');
while (<STDIN>) {
print $WTR $_;
}
close($WTR); # finish sending all output to sort(1)
while (<$RDR>) { # now read the output of sort(1)
print STDOUT "$_";
}
More generally, you may have to use
select
to determine which file
descriptors are ready to read, and then
sysread
for the actual
reading.
The IPC::open3 module shows an alternative that handles
STDERR
as well.