这篇“怎么使用Perl和Expect登陆多台设备批量执行命令”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用Perl和Expect登陆多台设备批量执行命令”文章吧。
登陆多台设备
设备登陆信息按如下格式存放于文件中。
$ cat
在每台设备上批量执行命令
要执行的命令集合按如下格式存放于文件中。
$ cat cmds.txt date w ifconfig more
Perl脚本实现,使用了Expect模块
借助Expect模块实现登陆,执行命令,捕获命令回显,取日志,自动回复more分页,ping探测主机等功能。脚本中的语句形式可供参考。
脚本如下:
#! /usr/bin/perl #安装模块 #cpan #install Expect #install Net::Ping #perl -MCPAN -e "install autodie" use utf8; use Expect; use autodie; use Net::Ping; #0为关闭本地回显 #$Expect::Log_Stdout=0; $ENV{TERM}="xterm"; #不进行缓冲直接进文件 #$|=1; #cmds.txt的文件格式: #一行一条命令 my @cmds; my $cmds_file="./cmds.txt"; open CMDS,"<",$cmds_file or die "Can't open file $cmds_file: $!\n"; print "commands to run: \n"; while(<CMDS>){ print "$_"; chomp; push @cmds,$_; } close CMDS; print "=============================\n"; mkdir 'log' unless -e 'log'; chomp(my $now=`date +%y%m%d`); my $exp=Expect->new; #$exp->raw_pty(1); #hosts.txt的文件格式: #IPv4地址:主机名:登陆方式(ssh/telnet):用户名:密码 my $hosts_file="./hosts.txt"; open HOSTS,"<",$hosts_file or die "Can't open file $hosts_file: $!\n"; while(<HOSTS>){ chomp; @host=split /:/; if(&ping_host(@host)){ &login_host(@host); } } close HOSTS; print "Loging finished!\n"; #子程序 sub{ print "login to $_[1]($_[0])...\n"; my $user=$_[3]; my $passwd=$_[4]; my $ahost=$_[1]; if($_[2] =~ /ssh/i){ $exp=Expect->spawn("ssh -l $user $_[0]") or die "Can't login to $_[1]($_[0]): $!\n"; $exp->expect(3, [ #使用正则来表达包含关系 qr/connecting\s\(yes\/no\)\?/i, sub { my $self=shift; $self->send("yes\n"); exp_continue; } ], [ qr/password:/i, sub { my $self=shift; $self->send("$passwd\n"); exp_continue_timeout; } ] ); #取log $exp->log_file("log/$_[1]-$now.log", "w"); $exp->send("\n"); foreach (@cmds){ $exp->send("$_\n"); $exp->expect(2, [ #使用正则来表达包含关系 qr/\[>#$\]/, sub { my $self=shift; $self->send("\n"); exp_continue_timeout; } ], [ qr/--More--/i, sub { my $self=shift; $self->send(" "); exp_continue; } ] ); } #关闭log $exp->log_file(undef); #退出登陆 $exp->send("exit\n") if ($exp->expect(undef,'-re' => '[>#$]')); #undef是痴等 print "\nLogout from $_[1]($_[0])\n"; }else{ $exp=Expect->spawn("telnet $_[0]") or die "Can't login to $_[1]($_[0]): $!\n"; $exp->expect(30, [ #使用正则来表达包含关系,否则就是精确匹配 qr/$ahost login:/i, sub { my $self=shift; $self->send("$user\n"); exp_continue; } ], [ qr/Password:/i, sub { my $self=shift; $self->send("$passwd\n"); exp_continue_timeout; } ] ); #取log $exp->log_file("log/$_[1]-$now.log", "w"); $exp->send("\n"); foreach (@cmds){ $exp->send("$_\n"); $exp->expect(2, [ #使用正则来表达包含关系,否则就是精确匹配 qr/\[>#$\]/, sub { my $self=shift; $self->send("\n"); exp_continue_timeout; } ], [ qr/--More--/i, sub { my $self=shift; $self->send(" "); exp_continue; } ] ); } #关闭log $exp->log_file(undef); #退出登陆 $exp->send("exit\n") if ($exp->expect(undef,'-re' => '[>#$]')); #undef是痴等 print "\nLogout from $_[1]($_[0])\n"; } } sub{ $p=Net::Ping->new("icmp"); #需要root权限 if($p->ping($_[0])){ print "$_[1]($_[0]) is alive\n"; return 1; }else{ print "$_[1]($_[0]) is die\n"; return 0; } }
如果没有root权限
ping_host子程序可以替换为如下调用系统ping命令的方法
use Net::Ping::External qw(ping); ... sub{ my $alive = ping(host => $_[0]); if($alive){ print "$_[1]($_[0]) is alive\n"; return 1; }else{ print "$_[1]($_[0]) is die\n"; return 0; } }
以上就是关于“怎么使用Perl和Expect登陆多台设备批量执行命令”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。