喬遷啟示:因應實體教室租約到期,富捷培訓於八月起將在長安新址,以線上直播教學為您服務,懇請舊雨新知繼續支持與指教。 地址:台北市長安東路二段201巷19號之1一樓,電話: 02-27116373

11 六月 2013

PERL fork – 平行多程序fork()存取Cisco設備的PERL程式

作者:Ben哥|發布日期:2012/12/18

Cisco PERL Fork Telnet Script:

本PERL fork 程式利用telnet取得每個 Cisco 路由器或交換器的組態之訊息,所需時間約2秒鐘,如果貴公司有1,000台 Cisco 設備,一般單執行緒(single thread)程式恐耗時2,000秒相當於33+分鐘,此 PERL fork 程式使用平行多程序同時對所有的Cisco設備進行存取,所需時間可能不到10秒鐘;請各位試試看。

  1. 執行成功訊息輸出(scalar type)儲存於$hostinfo{ 主機名稱 }->{ 執行指令 }
  2. 執行失敗訊息輸出(scalar type)儲存於$hosterrinfo{ 主機名稱 }->{ 執行指令 }

奇科視頻教學

執行 PERL fork 程式的過程及講解

原始碼如下:
#!/usr/bin/perl -w

# This perl script is main to be doing numeric cisco equipment management

use strict;
use IPC::Shareable;

$SIG{ ‘CHLD’ } = ‘IGNORE’;

my @hosts = ( ‘主機名稱或IP定址’, ‘主機名稱或IP定址’ );

my @cmds = ( ‘sh geego’, ‘sh ver’, ‘sh clock’, ‘sh queueing’, ‘sh hosts’ );

my $username = ‘登入帳號名稱’;  # cisco telnet 的帳號

my $passwd = ‘帳號之密碼’;    # cisco telnet 的密碼

my $enable_passwd = ‘enable的密碼’;

my %hostinfo = ();

my %hosterrinfo = ();

my @children = ();

my %ipcoptions = ( create => ‘yes’,

exclusive => 0,

mode => 0644,

destroy => ‘yes’ );

tie %hostinfo, ‘IPC::Shareable’, ‘good’, \%ipcoptions or die “Can’t tie %hostinfo.\n”;

tie %hosterrinfo, ‘IPC::Shareable’, ‘err’, \%ipcoptions or die “Can’t tie %hosterrinfo\n”;

foreach my $host ( @hosts )
{
my $pid = fork();

die “Can’t fork.:$!\n” unless defined( $pid );

if( $pid == 0 ) # this is child process
{

print “Child process is $$\n”;

get_info( $host );

exit( 0 );
}
else # This is parent process
{
print “$$ -> Process $pid is processing $host now.\n”;
push( @children, $pid );
}

}

foreach ( @children )
{
#my $child_pid = waitpid( $_, 0 );
my $child_pid = wait();
print “Process $_ is done.\n”;
}

sub get_info
{

use Net::Telnet::Cisco;  # 特別的 Perl Cisco Telnet的模組

my ( $hostname ) = @_;

my $cisco = Net::Telnet::Cisco->new( ‘Host’ => $hostname,

‘Errmode’=> ‘return’ );  # Perl Cisco Telnet的物件初始化

$cisco->login( Password => “$passwd” );

$cisco->ignore_warnings;

foreach my $cmd ( @cmds )

{

my @output = $cisco->cmd( “$cmd” );

if( $cisco->errmsg() )

{

$hosterrinfo{ $hostname }->{ $cmd } = $cisco->errmsg();

}

else

{

my $out = join( “”, @output );

$hostinfo{ $hostname }->{ $cmd } = $out;

}

}

}

foreach my $host ( keys %hostinfo )

{

foreach my $cmd ( keys %{$hostinfo{ $host }} )
{

print “$host => $cmd =>\n $hostinfo{ $host }->{ $cmd }\n”;

}

}