hi all, I want to run a interactive command using POE::Wheel, I met some
problem.
Here is my code:
###main.pl
use POE qw( Wheel::Run );
POE::Session->create(
inline_states => {
_start => \&on_start,
got_child_stdout => \&on_child_stdout,
got_child_stderr => \&on_child_stderr,
got_child_close => \&on_child_close,
got_child_signal => \&on_child_signal,
read_from_stdin => \&read_from_stdin,
}
);
POE::Kernel->run();
exit 0;
sub on_start {
my $child = POE::Wheel::Run->new(
Program => ["perl get_name.pl" ],
StdoutEvent => "got_child_stdout",
StderrEvent => "got_child_stderr",
CloseEvent => "got_child_close",
);
$_[KERNEL]->sig_child($child->PID, "got_child_signal");
$_[HEAP]{children_by_wid}{$child->ID} = $child;
$_[HEAP]{children_by_pid}{$child->PID} = $child;
$_[HEAP]->{job} = $child;
print("Child pid ", $child->PID, " started as wheel ", $child->ID,
".\n");
$_[KERNEL]->yield('read_from_stdin');
}
sub on_child_stdout {
my ($stdout_line, $wheel_id) = @_[ARG0, ARG1];
my $child = $_[HEAP]{children_by_wid}{$wheel_id};
print "pid ", $child->PID, " STDOUT: $stdout_line\n";
}
sub on_child_close {
my $wheel_id = $_[ARG0];
my $child = delete $_[HEAP]{children_by_wid}{$wheel_id};
unless (defined $child) {
print "wid $wheel_id closed all pipes.\n";
return;
}
print "pid ", $child->PID, " closed all pipes.\n";
delete $_[HEAP]{children_by_pid}{$child->PID};
}
sub on_child_signal {
print "pid $_[ARG1] exited with status $_[ARG2].\n";
my $child = delete $_[HEAP]{children_by_pid}{$_[ARG1]};
# May have been reaped by on_child_close() .
return unless defined $child;
delete $_[HEAP]{children_by_wid}{$child->ID};
}
sub read_from_stdin{
$_[HEAP]->{job}->put("woosley\n");
$_[HEAP]->{job}->put("password");
}
##### get_name.pl
use Term::ReadKey;
my %hash;
get_user();
sub get_user {
print "Input Your User Name:\n";
$hash{user} = <STDIN>;
chomp $hash{user};
print "get $hash{user}\n";
print "Input Your Password:\n";
ReadMode 2;
$hash{pass} = <STDIN>;
chomp $hash{pass};
print "get $hash{pass}\n";
ReadMode 0;
}
when I run main.pl, I got output like this:
Child pid 16857 started as wheel 1.
pid 16857 STDOUT: Input Your User Name:
pid 16857 STDOUT: get woosley
pid 16857 STDOUT: Input Your Password:
pid 16857 STDOUT: get
pid 16857 closed all pipes.
pid 16857 exited with status 0.
Apparently I failed to get the password but get the last "\n" in the first
input to password. But if I got rid of "\n", the whole script just blocked.
How can I deal with such a situation?
Besides, if I want to read the input from STDIN instead of writing them in
the code, I need to rewrite the read logical again in sub "read_from_stdin",
reading the input and put it to the childprocess, is there a stdinEvent that
can handle this task for us?
Thanks
--
Woosley.Xu
Tju->PMO->Rdps