I have no experience with Expect.pm, so maybe that is
what you want, but if not, or you want to stick with
modules that are part of the standard distribution,
IPC::Open2 and IPC::Open3 give you the ability to open
pipes both to and from a child process. Something like
(untested):
use IPC::Open2;
local (*RD, *WR);
my $child = open2(\*RD, \*WR, 'passwd');
# RD and WR are now pipes connected to STDOUT/STDERR and
# STDIN respectively of the child process. $child contains
# the PID.
my $prompt = <RD>; # not caring what the prompt is, here
print WR "password\n";
$prompt = <WR> # prompted again
print WR "password\n";
Though, to make the code robust, you will want to check the prompts, and probably deal with SIGCHLD yourself so you can get return conditions and so on. You should also set an alarm to time out if something blocks unexpectedly.
Andrew.