in reply to Telnet command with more than 1024 chars

Hello ElectricCheese,

Welcome to the monastery. Well I want to ask one question, why telnet and not any other alternative? See Best module to execute administrator commands on external operating systems (Linux) for possible alternatives with samples of code. I know the title says Linux but the modules and samples of code should apply on WindowsOS also.

Update: Check max_buffer_length - maximum size of input buffer. From the module documentation:

$len = $obj->max_buffer_length; $prev = $obj->max_buffer_length($len);

Update2: Or you can use cmd - issue command and retrieve output use die for the command and eval to capture error:

$ok = $obj->cmd($string); $ok = $obj->cmd(String => $string, [Output => $ref,] [Cmd_remove_mode => $mode,] [Errmode => $mode,] [Input_record_separator => $chars,] [Ors => $chars,] [Output_record_separator => $chars,] [Prompt => $match,] [Rs => $chars,] [Timeout => $secs,]);

Sample from Trying to capture error message using telnet::net, sample of code untested.

eval { my @lines = $obj->( String => 'who', # your long command here Errmode => 'die' ); }; if($@) { print $@; } else { print "success\n"; }

Maybe this could help.

Looking forward to your reply, if you only want telnet and nothing else, BR.

Seeking for Perl wisdom...on the process of learning...not there...yet!

Replies are listed 'Best First'.
Re^2: Telnet command with more than 1024 chars (updated)
by ElectricCheese (Initiate) on Jul 19, 2017 at 18:38 UTC

    Thank you for you quickly response thanos!

    I have updates... first of all, my fellow monk, apologizes this young grasshopper. My command line have a lot of e-mails, and I forgot to escape them in my test script. So part of the problem is solved: the "More? " is coming in the result, and the waitfor is working. NICE.

    However, in the ideal world, I shouldn't be concerned about a command line with 1024 chars limitation, this is awkward. The "More? " shouldn't NEVER be asked... So I'm opened to ideas that fix this. So I checked the max_buffer_length and returned its default value: 1048576 bytes, 1 MiB. Well, I'm not sure, but I suspect this behavior should be on server side.

    Regarding about why telnet, your're absolutely right. AFAIK, the best option should be SSH. But this server is maintained by another team, I'll ask them if it is possible to change to SSH. Thanks for minding about this.

    I'm still working on print and waitfor... updates will come.

      Hello again ElectricCheese,

      Why don't you try to get the byte size of the command (145 characters) with Devel::Size or bytes.

      By doing this you will now if you are exceeding the maxim transmission size (1,048,576 bytes) see the documentation from the module Net::Telnet for max_buffer_length - maximum size of input buffer.

      I am not only suggesting to use ssh because you will avoid all these problems, I am suggesting it because of many many reasons. Read an short article about the comparison Telnet & SSH.

      Hope this helps, BR.

      Seeking for Perl wisdom...on the process of learning...not there...yet!

        Hello thanos1983!

        Well, I decided to use a different approach instead of using $t->print and $t->waitfor, I decided to use line continuation character, and I discovered it worked very well! I found this code here and adapted for my needs, on which it fitted well. There says some shells have a limitation of 255 characters line limit.

        sub cmd_unixlong { my ($obj, $cmd) = @_; my ($line, $pos); my $max_tty_line = 254; ## Start a Bourne shell. $obj->cmd(-string => "/usr/bin/env " . "'PS1=<xPROMPTx> ' 'PS2=<xPROMPTx> ' /bin/sh -i", -prompt => '/<xPROMPTx> $/') or return; ## Break-up the one large command line and send as shorter lin +es. $pos = 0; while (1) { $line = substr $cmd, $pos, $max_tty_line; $pos += length $line; last unless $pos < length $cmd; ## Send the line with continuation char. $obj->cmd(-string => "$line\\", -prompt => '/<xPROMPTx> $/') or return; } ## Send the last line and return the output. $obj->cmd("$line ; exit"); } # end sub cmd_unixlong
        I'm still using telnet, so I changed it to something more or less like this:
        sub cmd_telnetlong { my ($obj, $cmd) = @_; my ($line, $pos); my $max_tty_line = 254; ## Break-up the one large command line and send as shorter lin +es. $pos = 0; while (1) { $line = substr $cmd, $pos, $max_tty_line; $pos += length $line; last unless $pos < length $cmd; ## Send the line with continuation char. $obj->cmd(-string => "$line^", -prompt => '/More?/i') or return; } ## Send the last line and return the output. return $obj->cmd("$line ; exit"); } # end sub cmd_unixlong

        As I haven't found anything to solve the line limitation, this workaround served me very well! Thanks all for your time!

      While I'd second going to a different protocol than telnet, I know SSH has to be installed from external sources, e.g. Cygwin or KpyM. Perhaps on newish systems with their "Linux subsystem" it might be included.

      However, your problem sounds similiar to one that occurs when accessing routers, which typically default to paging after 24 lines and/or inserting line breaks after 80 characters. So my suggestion is: telnet in manually, issue the "escape character" (usually something like ctrl+] ), and enter "display". According to this, that should show you the parameters that are in effect. Perhaps you can see/set line width and/or page length there. In that case, Net::Telnet's option_state, option_send, etc. could be used.

        Hi soonix, I gave a look at you suggestion, indeed I thought there were should be a setting but unfortunaly I didn't found anything useful. Regarding the TELNET protocol, it is a legacy server, but I doubt if the infra team are willing to change the server... But thanks for your help my fellow monk!