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

Hi guys, i have a problem with the following code:
#start input of commands in telnet #---------------------------------- $telnet->waitfor('/\# $/i'); $telnet->print($cmd); @output=$telnet->waitfor('/Press any key to continue \(Q to quit\)/'); + $telnet->print('c'); #virtually press c key @output2=$telnet->waitfor('/\# $/i'); push(@output,@output2); $telnet->waitfor('/dfs=l,gdmgll<>ifdgoij$/i'); #creates a deliberate e +rror for error logging $fault=$telnet->errmsg; $telnet->close; if ($fault!="") { print "you got an error; }
Basically i don't want to make several outputs for the displaying of the commands of a switch we have, for now for every "press a key" I need to attach a new array to the older one, is there any way around this? I found out if I try a prompt and do the things manually it also asks a keypress for the next page, but not if i make the prompt screen larger. Perhaps there's a way to incorperate this in the telnet command or something? Also i want do an action if i get an error from the telnet command, the above code doesn't work if i do a $fault is not empty it still skips it, even when i print $fault it says: 'pattern match timed-out' (as it should be) however, i never get to the code with the check if $fault is empty Any suggestions? As i am new to the perl language they will be highly noted. Thanks in advance

Replies are listed 'Best First'.
Re: telnet with keypress and errmsg problem
by jakobi (Pilgrim) on Sep 30, 2009 at 15:53 UTC

    just concerning the 'attach' - if I understand you correctly you want to combine push & method invocation: use push @out, $telnet-> ...

    Wrt prompts: This might be worth an attempt to make the server's telnetd see a larger terminal: TERM=dumb LINES=9999 command .... With command being either telnet or perl. But also check the module's docs.

    Wrt errors: start with checking function/method returns: the return value plus possibly $! and $?.

    $rc=$telnet->... ; die "$rc==$?==$!" if not $rc or $?;

    Info on what to expect should be stated in e.g. perldoc -f / perldoc -m.

      hi, thanks for the input.
      The explanation of the push command was really helpfull,didn't notice you could just add the other command in it, without putting that command in a variable. It also made my code a little shorter ^^.

      Where should i make the insert of TERM=dumb LINES=999 i've read the telnet module documentation, but haven't come across those properties :s?

      Also the thing is: i'm making the perlscript on a windows command prompt, i've should've stated that earlier on :s.

      also the code: $rc=$telnet->... ; die "$rc==$?==$!" if not $rc or $?; doesn't seem to do anything, or am i doing something wrong? Even if i replace the 'die' with print (because my perl doesn't recognize the 'die' command)

      Thanks again for the input, i appreciate it!

        The press any key issue:

        That's a only quick guess: TERM=dumb LINES=999 perl your-script-name in a unix shell would set 2 environment variables for the command in question. Both are related to terminal settings, with COLUMNS and LINES providing the size of the terminal to apps that don't want to talk to the terminal directly using esc sequences (just don't go there!). At least TERM is honored by a real telnet command. Perl sees them in %ENV, maybe Net::Telnet would use them. Might also be worth a try for the server application.

        The telnet protocol offers two modes of operation: IIRC, with line mode the client offers just a truly basic line-oriented terminal to the service, with line-editing done by the client locally, w/o involving the server. In char mode the server would be able to talk to the remote tty (in the shell of an xterm, invoke telnet HOST to an insecure host still running a telnetd (the service), login to HOST's shell. If necessary set TERM=xterm and voila full screen vi or emacs.)

        For more info, check e.g. wikipedia, the original telnet protocol rfc 854 or the manpages of telnet and telnetd.


        Things to try coping with the press any key prompt (use a telnet client instead of perl for testing these interactively)

        • check for a setting in the service you connect to make it assume a huge number of lines. Maybe add LINES=9999999 in the start script or check for switches offered by the service. Maybe the service offers a command for display/lines/terminal settings in its user interface. If it's a real unix shell you connect to, try export LINES=99999 and maybe export TERM=dumb.
        • have waitfor accept full lines and explicetely deal with prompts as they occur. Fugly.
        • Net::Telnet has these suspicious exported constants (lflow's probably not of interest, but the rest might be good keywords for a search)
          sub TELOPT_NAOL () {8}; # Output Line Width sub TELOPT_NAOP () {9}; # Output Page Size sub TELOPT_NAWS () {31}; # Negotiate About Window sub TELOPT_LFLOW () {33}; # Remote Flow Control sub TELOPT_LINEMODE () {34}; # Linemode
        • Super Search
        • search.cpan.org
        • google.com with some terms like telnet prompt lines terminal

        If you've found your answer, please append it to this thread :)

Re: telnet with keypress and errmsg problem
by jakobi (Pilgrim) on Oct 01, 2009 at 14:56 UTC
    Notes on timeout:
    • do run the code scrap you provide: Lack of providing $cmd, lack of information of service to connect to, lack of providing module use statements, use of != instead ne for string comparison, lack of closing quote (both in final print). Just a quick edit-down for posting will bite you and those you ask. Reliably. Every time.
    • I've used the mail daemon as example service for my test. http / port 80 is also quite telnet-friendly.
    • the key to your problem is to remember that modules can create errors and choose to die or carp. Use eval{} to avoid that. That way the script continues beyond the timeouting waitfor. So of course the die and prints didn't trigger.
    • Note that there's a second $?, this time in the shell/invoking process (i.e. outside of your perl script): print $? or echo $? showing a value other than 0 would have alerted you to the fact that your script didn't exit as expected (fall-of-the-end-of-the-world aka implied exit(0)).
      This holds at least for Unix and should also hold for cygwin. No bets on windows cmd. On Unix/Cygwin do consider including $? in your $PS1 shell prompt.

    The output for me annoying a postfix mailer daemon is: