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

Good afternoon,
I am having difficulty with integrating the Net::Telnet with my prompt. I am developing some Perl code to log into an account with Net::Telnet and have it execute several commands, but am having trouble making the regular expression that searches for different shell prompt types work for a wide variety of different prompts (this is contained in the 'Prompt' variable of the Net:Telnet module).


My code to initiate the login and execute a command looks like this
(this code is just for testing purposes, so forgive the failure to follow various Perl conventions):
#!/usr/bin/perl -w use strict; my $hostname="localhost"; my $port=23; #my $username="testuser1"; #my $password="1helpnow"; #my $username="testuser2"; #my $password="1please"; my $username="testuser3"; my $password="1password"; use Net::Telnet(); my $t = new Net::Telnet (Timeout=>10, Prompt=> '/[\$%#>\d\w\r] $/'); $t->dump_log("log.telnet.dat"); $t->open(Host => $hostname, Port => $port); $t->login($username, $password); my @lines = $t->cmd("who"); $t->lastline; $t->close; print "@lines\n";
My problem is that for testuser1 and testuser3, I was not able to log in while, testuser2 logs in beautifully. I have isolated the problem and have determined that it lies in each user's .bashrc file, in particular, the PS1 line in the file.
The .bashrc file for testuser1 and testuser3 were exactly the same. The PS1 file for those two users looks like this: (Hang with me here... this really is a Perl question)
RED="\[\033[1;31m\]" # Color Definitions for bash LIGHT_RED="\[\033[1;31m\]" BLUE="\[\033[1;34m\]" WHITE="\[\033[1;37m\]" NC="\[\033[0;0m\]" # No Color PS1="${TITLEBAR}\ $BLUE[$RED\$(date +%I:%M)$BLUE]\ $BLUE[$LIGHT_RED\u@\h:\w$BLUE]$WHITE#$NC "

When I remove the $NC from the end of the PS1 prompt, I am able to log in successfully with Net::Telnet. However, since there are users who may be using this .bashrc file, I have to support it with my perl script. Therefore, I must create a regular expression for the Net::Telnet 'Prompt' variable that will treat the $NC (or any other strange character sequence that someone might use for a shell prompt) in the same way that it does for a # $ % or >.
I have read carefully through the Net::Telnet documentation, but have had no luck finding much that is helpful. I have also tried using the regular expressions found in reg ex and the prompt but have had no luck. If anyone has had any experience with Net::Telnet and has any suggestions regarding this topic, I would be very grateful to hear what you have to say. Thank you for reading this.

Replies are listed 'Best First'.
Re: Net::Telnet stalls
by JamesNC (Chaplain) on Jun 18, 2003 at 22:03 UTC
    Try setting the Input_Log=> $file and Output_Log=>$file args up in your new and examine the output from that session. I would check to see what type of terminal Net::Telnet thinks it is talking to also. It looks like you are Linux or Unix box, but the following info may help troubleshoot...

    On Windows 2000/XP, Net::Telnet has a problem finding the command prompt and the output because the Microsoft Telnet Server dumps ANSI escape codes into the output. As a result (on Win32 anyway) you have to parse out the weird ANSI codes. (My point... if the Telnet Servers are not the same, you may not get the same results... why? Net::Telnet doesn't negotiate all of the Telnet Opts as best I can tell... If a Server doesn't successfully negotiate a Command Code, it is supposed to drop back to a RFC854 compliant mode... but it doesn't always... uggh... I could go on...) So... look in the log files.. if you see stuff like ~12;1H~Kc:\> in your output then the telnet server is sending ANSI escape codes...

    With that being said, I got frustrated with the ANSI codes interfering with the output so 2 weeks ago I found all of the ANSI escape codes for VT52 and VT100 Terminal Emulations and built a module to escape them all from the Net::Telnet buffer using RegExs.

    I was still having problems with Net::Telnet's approach of waiting for a specific pattern match, so I decided to build a Telnet client as an exercise that just spits out the text clear of ANSI codes from whatever command you send to the Telnet client.

    BOTTOM LINE POSSIBLE SOLUTION: If you or someone else needs to escape VT52/VT100 codes. Post a reply and I will put the Module in your node.... or if you want a Simple Telnet Client codes lemme know and I will e-mail it to you or post it here if folks think it's ok.. it is about 150 lines... hope this wasn't too verbose...

    Cheers,
    James :)
      Thank you very much for the information regarding this module. I would like to see the module that you have to offer. I am still new to using this telnet moudule and appreciate anything that would make the details of Net::Telnet more evidant to me and would be curious to see your alternative to it. If you are afraid that the code will be too long for a post here, just place it in the snippits section. I really appreciate your post. Thanks again!
Re: Net::Telnet stalls
by sgifford (Prior) on Jun 19, 2003 at 01:32 UTC
    As your first command, before you scan for the prompt, set their prompt; just send
    PS1='$'
    export PS1
    
    But you don't know for sure what shell they'll have, so why not start up the one you want?
    exec env PS1='$' /bin/bash
    
    You might want to set their path, too, to make sure you're really running the program you expect to be. In fact, why not clear out their current environment and start up bash without reading their .bashrc or .profile at all?
    exec env - PS1='$' PATH=/usr/bin:/bin /bin/bash --norc --noprofile
    
      Is that possible under Net::Telnet? forgive my ignorence but i thought that it automatically checked for a prompt as part of the login() sub, I may be, and likely am wrong on this but it was my understanding that the scanning for a prompt was automatic.

      but as i am likely wrong on this (im not terribly familiar with Net::Telnet) it is a good idea

      This is an interesting idea. I never really knew that you could prevent the bashrc from being read when you enter a shell... or at least I never really knew how. This is useful. I will definately look into this. Thank you very much.
Re: Net::Telnet stalls
by MZSanford (Curate) on Jun 18, 2003 at 20:02 UTC
    Maybe something like the untested :
    Prompt => '/([\$%#>\d\w\r]|\\\[\S+\\\]) $/'
    To allow any escape sequences ? This is untested and probably does not work. probably has missing and/or extra slashes, etc ... but you get the idea.
    from the frivolous to the serious
      Thanks! I will poke around with that.