Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Unable to match Net::Telnet Prompt on CentOS. However, the same prompt works fine on FC20

by shoundic (Novice)
on Jan 16, 2019 at 10:45 UTC ( #1228644=perlquestion: print w/replies, xml ) Need Help??

shoundic has asked for the wisdom of the Perl Monks concerning the following question:

I've a script which works fine on FC20. But, when I try to execute the same script on CentOS(CentOS Linux release 7.5.1804 (Core)), it hangs. On further, investigation it was revealed that, it is not able to match the prompt given. Please note it is able to match host prompt but not application prompt. Here is a brief detail of the issue

Code of the wrapper function which is used to create object of Net::Telnet-

package api::Telnet; use strict; use warnings; use Net::Telnet; use Exporter; use Carp; our @ISA = qw (Exporter); our @EXPORT = qw ( &open_pty &close_pty ); # Constant global variables use constant SSH_TIMEOUT => 1800; sub spwan_pty { my (@cmd) = @_; my ($pid, $tty, $tty_fd); # Create a new pseudo terminal use IO::Pty (); my $pty = new IO::Pty or die $!; # Execute the program in another process # Child process unless ($pid = fork) { die "problem spawning program: $!\n" unless defined $pid; # Disassociate process from existing controlling terminal use POSIX (); POSIX::setsid or die "setsid failed: $!"; # Associate process with new controlling terminal $pty->make_slave_controlling_terminal; $pty->set_raw(); $tty = $pty->slave(); $tty_fd = $tty->fileno; close $pty; # Make stdio use the new controlling terminal open STDIN, "<&$tty_fd" or die $!; open STDOUT, ">&$tty_fd" or die $!; open STDERR, ">&STDOUT" or die $!; close $tty; exec @cmd or die "problem executing $cmd[0]\n"; } # end child process $pty; } sub open_pty { my (%args) = @_; # Start ssh program. my $pty = &spwan_pty("ssh", "-l", $args{user_name}, "-e", "none", "-F", "/dev/null", "-o", "PreferredAuthentications=password", "-o", "NumberOfPasswordPrompts=1", "-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null", $args{ip_addr} ); # Create a Net::Telnet object to perform I/0 on ssh's tty my $ssh = new Net::Telnet ( -fhopen => $pty, -prompt => $args{prompt}, -telnetmode => 0, -cmd_remove_mode => 1, -timeout => SSH_TIMEOUT, -output_record_separator => "\r", #-errmode => sub { print "Telnet FAIL\n"; } ); # Wait for the password prompt and send password. $ssh->waitfor(-match => '/password: ?$/i', -errmode => "return") or die "problem connecting to \"$args{ip_addr}\": ", $ssh->las +tline; $ssh->print($args{user_pswd}); # Wait for the shell prompt. my (undef, $match) = $ssh->waitfor( -match => $ssh->prompt, -match => '/^Permission denied/m', -errmode => "return" ) or return $ssh->error("login failed: expected shell prompt ", "d +oesn't match actual\n"); return $ssh->error("login failed: bad login-name or password\n") i +f $match =~ /^Permission denied/m; # logging $ssh->input_log($args{log_file}); $ssh->cmd("ifconfig"); $ssh->cmd("date"); return $ssh; } sub close_pty { my ($tty) = shift; $tty->close(); } 1;

Once Net:Telnet object is obtained, it is used to spawn an interactive application. Here is the code snippet of the same-

my $host_prompt = '/[\$%#>] $/'; my $util_prompt = '/(\s)*Command: (\s)*/i'; my $owner = &open_pty ( user_name => "<user_name>", user_pswd => "<password>", ip_addr => "127.0.0.1", prompt => $host_prompt, log_file => 'Log/Owner' ); $owner->cmd ( String => "cd <navigate to application path>", Prompt => + $host_prompt ); $owner->cmd ( String => "<Launch the application>", Prompt => $util_pr +ompt ); $owner->cmd ( String => "<Execute command>", Prompt => $util_prompt );

The code successfully creates a Net::Telnet object and spawn the application, but it is unable to match the prompt of the application, due to which it hungs and the script is unable to proceed forward. Here is the log generated-

em1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet xxx.xxx.xxx.xxx netmask 255.255.252.0 broadcast xxx.xxx +.xxx.xxx inet6 xxxx::xxxx:xxxx:xxxx:xxxx prefixlen 64 scopeid 0x20<li +nk> ether xx:xx:xx:xx:xx:xx txqueuelen 1000 (Ethernet) RX packets 393842 bytes 40650026 (38.7 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 138388 bytes 15595013 (14.8 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 16 memory 0x92f00000-92f20000 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 5296 bytes 928222 (906.4 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 5296 bytes 928222 (906.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx broadcast xxx.x +xx.xxx.xxx ether xx:xx:xx:xx:xx:xx txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@hyd1658 ~]# Wed Jan 16 15:29:54 IST 2019 . . . . Command:

Please Note: The same code works on FC20, but fails on CentOS

Could anyone please pinpoint the issue or suggest a remedy for the same

  • Comment on Unable to match Net::Telnet Prompt on CentOS. However, the same prompt works fine on FC20
  • Select or Download Code

Replies are listed 'Best First'.
Re: Unable to match Net::Telnet Prompt on CentOS. However, the same prompt works fine on FC20
by VinsWorldcom (Prior) on Jan 16, 2019 at 19:11 UTC

    You could set:

    my $obj = Net::Telnet->new( ... dump_log => 'dump.log', .... } # or $obj->dump_log('dump.log');

    on your Net::Telnet object to get a "binary" log file showing all the hex characters of what's on the wire - then you could see any funky escape characters in the prompt as suggested by RMGir above.

      Thanks, by using dump_log I was able to solve the issue.
        Excellent! But now I'm curious: what was it? :)

        Mike
Re: Unable to match Net::Telnet Prompt on CentOS. However, the same prompt works fine on FC20
by RMGir (Prior) on Jan 16, 2019 at 18:42 UTC
    My guess would be that CentOS is sending you a colourized or otherwise escape-sequence-mangled prompt, but it's hard to tell.

    Have you tried using wireshark to see what's actually being sent over the wire, to make sure the prompt you expect is what you're sent? Just using 'telnet' isn't really enough, since you might not be able to see anything that's not printable. (Edit: Actually, as suggested below, use the dump_log option - it sounds much simpler than wireshark).


    Mike
Re: Unable to match Net::Telnet Prompt on CentOS. However, the same prompt works fine on FC20
by kschwab (Vicar) on Jan 16, 2019 at 19:17 UTC
    You could try copying the .bashrc and any other shell config scripts from the Fedora box to the Centos box. Make backups first.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1228644]
Approved by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2019-10-23 22:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?