当使用Perl的Net::Telnet连接时,如何修复“未知终端类型”错误?

7

我遇到了一个问题,使用Perl的Net::Telnet模块连接到SUSE Linux机器时无法连接。

代码如下:

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;

日志文件如下所示: 欢迎使用SUSE Linux Enterprise Server 10 SP1(x86_64)-内核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: unknown terminal type network
Terminal type? 

有什么建议吗?
4个回答

4
如果您使用option_log函数来记录接收和返回的telnet选项,您会发现Perl默认不向服务器发送终端类型。出于某些原因,服务器将默认终端类型设置为“network”。正确的方法是在Perl侧设置终端类型。
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:

参考这个


我曾经遇到一个连接OSGI Telnet服务的问题,这是由基于Eclipse的产品提供的。您的解决方案终于奏效了! - col.panic

1

另外一种方法是将问号添加到提示值中,然后将 echo $TERM 值作为第一个命令发送。因此,如果您的命令提示符是'>',而 echo $TERM 返回 '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";

1

关于同样的问题,请查看此次讨论。他们提出的解决方案(未经过测试)是将TERM环境变量设置为已知值,例如TERM=vt100


我看到了相同的讨论,但是怎么做呢?我需要在本地机器上执行"export TERM=vt100"命令还是在远程机器的.profile文件中为telnet用户执行该命令?谢谢! - root1982
在你的 Perl 脚本中,使用 @root1982 或者 $ENV{TERM}='vt100' - mob
谢谢大家。我仍然有同样的问题。 - root1982

0
在 /etc/profile 中,你应该找到以下这行代码:
test -x /usr/bin/tset && /usr/bin/tset -I -Q

这是导致问题的那一行。您可以通过运行以下命令进行确认:

$>TERM=network
$>/usr/bin/tset -I -Q
tset: unknown terminal type network
Terminal type? 

在 /usr/share/terminfo/n/ 中,network 是一个指向 ../n/net 的链接。我不知道为什么系统不能识别 "network"。

临时解决方法是更改 /etc/profile 中的行如下:

test -x /usr/bin/tset && /usr/bin/tset -I -Q -m network:vt100

以上命令将网络映射到vt100。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接