這篇“怎么使用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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。