平时,要自动ssh到远程主机上做操作时,都要建立信任关系,这样在连接时,才不用输入密码。 就想不用建立信任关系的情况下,来自动ssh连接到远程主机做操作。可以用提供一个所要连接的远程主机列表来实现这个功能。
列表里提供了主机IP,用户,密码,格式如下:
192.168.0.1 root 123456
192.168.0.2 root 654321
之前,有过一个自己写的难看的shell脚本,来实现抓取到远程主机的各种系统信息(monitor.sh,脚本见附件),通过Net::SCP::Expect模块来把这个脚本传到远程主机,再运行它,把所生成的日志报告再传回本地管理机上。这样来实现自动轮询抓取所有远程主机的系统信息到本地管理主机。
之前,有考虑过使用 Net:SCP 模块来实现传输文件的功能,但发现它没有输入密码的功能,也就是说两台相连接的主机之间,必须建立信任关系。
在perl里,有很多模块可以实现ssh连接远程主机做操作,以下是使用Net::SSH::Perl来实现的。
Perl脚本如下:
- use strict;
-
use warnings;
-
use Net::SCP::Expect;
-
use Net::SSH::Perl
-
-
open HOST_LIST, "Remote_host_list.txt" || die "can`t open this file\n";
-
-
while(<HOST_LIST>){
-
my ($host,$user,$passwd) = split;
-
my $scpe = Net::SCP::Expect->new(host=>"$host",user=>"$user",password=>"$passwd",auto_yes=>"1",verbose=>"1",timeout=>"30");
-
$scpe->scp("monitor.sh","/root");
-
-
my %params = (
-
protocal => '2,1',
-
# debug => '1'
-
);
-
-
my $ssh = Net::SSH::Perl->new($host,%params);
-
$ssh->login($user,$passwd);
-
-
$ssh->register_handler("stdout",sub{
-
my($channel,$buffer) = @_;
-
my $str = $buffer->bytes;
-
if($str =~ /(.*)\[Y\/n\/\?\]/i){
-
$channel->send_data("y\n")
-
}}
-
);
-
-
$ssh->cmd("/bin/bash /root/monitor.sh");
-
$scpe->scp("$host:/root/*.log","/root")
-
};
-
-
close HOST_LIST;
遇到的问题:
1. 通配符 "*" 问题
发现,从local to remote时,$scpe->scp("/root/*.log","/root")不成功,只能具体指定一位文件名,如要多文件传输,只能一个一个的写,报错信息如下:
scp exited with non-success state: 256 at ./t.pl line 30
当 remote to local 时,$scpe->scp("$host:/root/*.log","/root")成功,可把.log的所有文件,都传到local本地。
2. 没法实现传输整个目录,建议使用rsync来实现。
monitor.sh.txt
阅读(2524) | 评论(0) | 转发(0) |