How can I fix "unknown terminal type" when connecting with Perl's Net::Telnet?
I got a problem connecting to a SUSE linux machine by Perl's Net::Telnet module. The code looks like below:
my $t = new Net::Telnet (Timeout => 20);
$t->open($server);
$t->input_log("telnet.log");
$t->login($user, $pass);
my @lines=$t->cmd($command);
print @lines;
The log file looks like below: Welcome to SUSE Linux Enterprise Server 10 SP1 (x86_64) - Kernel 2.6.16.46-0.12-default (5).
vm-sles10u5 login: <myuser>
Password:
Last login: Thu Feb 25 10:41:07 EST 2010 from <mymachine> on pts/5
tset: unkno开发者_C百科wn terminal type network
Terminal type?
Any suggestions?
If you use the option_log function to log the telnet options received and returned. You will see that Perl does not send the terminal type to the server by default. Server will default the terminal type to "network" for some reasons.
The right way to do this is to set the terminal type on the perl side.
my $termtype = 'vt100'; my $telopt_ttype_ok = '';
my $t = new Net::Telnet (Timeout => 5);
$t->option_callback(\&opt_callback);
$t->option_accept(Do=>Net::Telnet->TELOPT_TTYPE);
$t->suboption_callback(\&subopt_callback);
$t->open($server);
$t->input_log("runRemoteCommand_telnet.log");
$t->login($user, $pass);
$t->cmd($command);
exit 0;
sub opt_callback {
my ($obj, $option, $is_remote, $is_enabled, $was_enabled, $buf_position) = @_;
if ($option == Net::Telnet->TELOPT_TTYPE and $is_enabled and !$is_remote) {
$telopt_ttype_ok = 1;
}
1;
}
sub subopt_callback {
my ($obj, $option, $parameters) = @_;
my ($ors_old, $otm_old);
if ($option == Net::Telnet->TELOPT_TTYPE)
{
$ors_old = $obj->output_record_separator('');
$otm_old = $obj->telnetmode (0);
$obj->print("\xff\xfa", pack("CC", $option, 0), $termtype, "\xff\xf0");
$obj->output_record_separator($ors_old);
$obj->telnetmode ($otm_old);
}
1;
}
Refer to this
See this discussion for the same problem. The solution (untested) that they propose is to set the TERM enviromental variable to a known value, such as TERM=vt100
What works too is to add the question mark to your prompt value and then send as the first command the echo $TERM value. So if your command prompt is '>' and echo $TERM gives 'xterm':
my $t = new Net::Telnet ( Timeout => 3,
Prompt => '/[\?>]/',
Dump_log => $dumplog,
Host => $host,
Input_log => $inputlog,
Output_log => $outputlog,
);
$t->login($username, $password);
my @lines = $t->cmd("xterm");
@lines = $t->cmd("who");
print @lines, "\n";
@lines = $t->cmd("uptime");
print @lines, "\n";
In /etc/profile, you should find the following line:
test -x /usr/bin/tset && /usr/bin/tset -I -Q
This is the line that causing the problem. You can confirm with running the following command:
$>TERM=network
$>/usr/bin/tset -I -Q
tset: unknown terminal type network
Terminal type?
In /usr/share/terminfo/n/, network is a link to ../n/net. I don't know why system does not work for "network".
The temp fix is to change the line in /etc/profile to the following:
test -x /usr/bin/tset && /usr/bin/tset -I -Q -m network:vt100
The above command will map network to vt100.
精彩评论