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