From: Tom B. <70m...@gm...> - 2017-11-24 12:52:19
|
Dear Perl-Expect fellows, as the implementation for the interact-method within Expect.pm is far away from the TCL-Expect implementation (see https://rt.cpan.org/Public/Bug/Display.html?id=56997) I am trying to use the method set_seq as workaround. But there is a very hard nut I am trying to crack for two days now. I am not sure if its caused by a bug in the Expect.pm module or my understanding is wrong how to hand over escape sequences to the set_seq($sequence,\&function,\@parameters) method. For reproduction purposes you can find the whole script below. -------------------------------- SCRIPT BEGIN ------------------------------- #!/usr/bin/perl use strict; use warnings; use Expect; use feature qw(say); my %OPT = ( "login" => "tbrown", "host" => "rtr", "prompt" => "RTR#", "passwd" => "myPasswd", "timeout" => 2, ); my @command = ("/usr/bin/ssh", "-o StrictHostKeyChecking=no", "-o PreferredAuthentications=password", "-o PubkeyAuthentication=no", "$OPT{login}\@$OPT{host}"); my $exp = new Expect(); $exp = Expect->spawn(@command) or die "Cannot spawn $command[0]: $!\n"; $exp->expect(2,'-re',"password: "); $exp->send("$OPT{passwd}\r"); $exp->expect($OPT{timeout}, $OPT{prompt}); $exp->send("term length 0\r"); $exp->expect($OPT{timeout}, $OPT{prompt}); my @parameters = qw(Parameter1 Parameter2 Parameter3); my @tunnel_iface = 2; $exp->log_stdout(0); $exp->debug(3); $exp->exp_internal(1); $exp->slave->stty(qw(raw -echo)); ### Proper handling of the following escape sequences (keys F1 ~ F3) $exp->set_seq('\\033OP',\&sh_clock); $exp->set_seq("\\033OQ",\&sh_arp_vlan, \@parameters); $exp->set_seq("\\033OR",\&sh_vpn, \@tunnel_iface); ### Wrong handling of the following escape sequences (function keys F5) ### As with beginning of F5 the escape sequence pattern starts with '^[[15~' ### it looks like something goes wrong with the second '[' and the followed ### '15~' $exp->set_seq('\\033\[15~', \&leave); $exp->set_seq('X', \&leave); #$exp->set_seq('\x1b\x5b\x31\x35\x7e', \&leave); #$exp->set_seq('\\033\x5b15~', \&leave); #$exp->set_seq('\\033\\03315~', \&leave); #$exp->set_seq('\\033\x5b15~', \&leave); # \x5b = [ = escape character as hex $exp->log_stdout(1); $exp->debug(0); $exp->exp_internal(0); sub sh_clock { $exp->send("sh clock\r"); $exp->expect($OPT{timeout}, $OPT{prompt}); } sub sh_arp_vlan { foreach my $parameter (@_) { say $parameter; } $exp->send("show ip arp vlan 1\r"); $exp->expect($OPT{timeout}, $OPT{prompt}); } sub sh_vpn { my $iface = shift; $exp->send("show crypto isakmp sa\r"); $exp->expect($OPT{timeout}, $OPT{prompt}); $exp->send("show crypto ipsec sa interface tunnel $iface\r"); $exp->expect($OPT{timeout}, $OPT{prompt}); } sub leave { $exp->send("exit\r"); $exp->expect($OPT{timeout}, eof); } $exp->interact(); print "##### MATCHED:"; p $exp->exp_match(); --------------------------------- SCRIPT END -------------------------------- The output of debug on invocation and after login is the following: RTR#term length 0 RTR#Escape seq. '\033OP' function for spawn id(6) set to 'CODE(0x7f88318a72b8)()' Escape seq. '\033OQ' function for spawn id(6) set to 'CODE(0x7f88318a7240)()' Escape seq. '\033OR' function for spawn id(6) set to 'CODE(0x7f88318a70f0)()' Escape seq. '\033\[15~' function for spawn id(6) set to 'CODE(0x7f88318a6f70)()' Escape seq. 'X' function for spawn id(6) set to 'CODE(0x7f88318a6f70)()' My investigations so far: ------------------------------------- 1 ------------------------------------- $exp->set_seq('\\033\[15~', \&leave); By pressing F5 the string '5~exit' occurs on the routers shell. Obviously, the escape sequence seems to be divided and the string "~5" is passed within @_ to the function &leave). ------------------------------------- 2 ------------------------------------- $exp->set_seq('X', \&leave); By pressing just X I get the following: Value of @_ is:[] exit ### End of @_ Translating "Xexit"...domain server... # < mind the "Xexit"!!! Translating "### Value of @_ is:[] (8.8.8.8) (217.237.150.51) (217.237.148.22) @_ (8.8.8.8) (217.237.150.51) (217.237.148.22) % Unknown command or computer name,or unable to find computer address RTR#exit Connection to 192.168.3.1 closed. Conclusion: Instead calling the function &leave expect sends 'Xexit' to the router. Why??? But: In case just pressing "ESC" followed by X, the function leave() is properly called and logged out. Conclusion: Pressing ESC before X followed by a proper function call is the proof that the method set_seq works as it should - so far at least. ------------------------------------- 3 ------------------------------------- The following attempts (different variants to catch the escape sequence properly) doesn't work neither. $exp->set_seq('\x1b\x5b\x31\x35\x7e', \&leave); # escape sequence in hex #$exp->set_seq('\\033\\03315~', \&leave); # #$exp->set_seq('\\033\[15~', \&leave); #$exp->set_seq('\\033\x5b15~', \&leave); # \x5b = [ = Escape Character ----------------------------------------------------------------------------- I am at my wits' end. Any ideas or workarounds how to invoke functions properly by pressing function keys (using escape sequences)? I appreciate any comments. Thanks. T. |