我正在编写一个与远程服务器通信的脚本。我理解如何发送基本的shell命令,如“ls”或“find / | grep foo”。但我正在另一端执行交互式应用程序。
如果我调用$ ssh-> shell,我会从远程服务器收到提示,因此我知道SSH正在接收此提示。但后来我无能为力,因为脚本在shell中被阻止了。
我安装了两个处理程序。如果我使用脚本连接到基本的ssh主机,并执行shell命令,响应将传递给处理程序,所以我知道它们没问题。所以我希望我正在执行的应用程序的提示被发送到这些,但它不是。
#!/usr/bin/perl -w
use strict;
use Net::SSH::Perl;
my $host = 'rt.olsendata.com';
my $user = 'rtdemo';
my $pass = 'rtdemo';
my %params = ('debug' => 1,'protocol' => 2);
my $ssh = Net::SSH::Perl->new($host, %params);
$ssh->register_handler("stderr", sub{
my ($ssh, $packet) = @_;
receiveerrors($packet);
});
$ssh->register_handler("stdout", sub{
my ($ssh, $packet) = @_;
receivedata($packet);
});
my ($output, $errors, $exit) = $ssh->login($user, $pass);
此时我需要通过发送“1”来响应提示。但这被远程主机解释为shell命令,而不是对提示的响应。它返回错误“h:1:没有这样的文件或目录”。
如果您想尝试一下,可以使用代码顶部的demo ssh帐户。它是公开的。
编辑:我意识到Expect解决了这个问题,但我在Expect中找不到与register_handler()相同的东西。我是对的吗?
答案 0 :(得分:0)
答案 1 :(得分:0)
到目前为止最简单的解决方案是Net :: SSH :: Expect。下面是代码。登录后我立即发送“1”以响应提示(“1”是我想要的选择)。然后我得到另一个提示,因为我想要默认值,我只是发送\ n。然后我想永远地逐行读取输入。它就像一个魅力。
my $ssh = Net::SSH::Expect->new (
host => $host,
user => $user,
password=> $pass,
raw_pty => 1
);
my $login_output = $ssh->login();
my $prompt = $ssh->exec("1");
my $line;
$ssh->send("\n");
while ( defined ($line = $ssh->read_line()) ) {
print "$line\n";
}