note
thanos1983
<p>Hello again techman2006,</p>
<em>Now I am looking a way to automate these task as I have a around 8 such devices on which I need to send some common commands and some specific command (may be present in a file).</em>
<p>From my point of view and based on your sample code, I do not see your automation.</p>
<em># perl ssh.pl <host name> <port> <username> <password></em>
<p>You are probing a single device per time, instead of 8.</p>
<p>I have posted several links on my previous reply, did you take a look on them?</p>
<p>I think a solution to your problem could be much simpler, automated, easier and cleaner if you do something like that:</p>
<p>Sample of code from <a href="http://www.perlmonks.org/?node_id=1097510">Best module to execute administrator commands on external operating systems (Linux)</a>.</p>
<strong>Final Update 2 with better answer and output sample:</strong>
<p>So with no further delays this is the code for multiple devices. For sample purposes the code runs on my localhost.</p>
<readmore>
<code>
#!/usr/bin/perl
use Expect;
use strict;
use warnings;
use Data::Dumper;
use Net::OpenSSH;
use Config::IniFiles;
use Fcntl qw(:flock);
$| = 1;
# To see the complete debuging process
#$Net::OpenSSH::debug = ~0;
my $path = 'conf.ini';
my $timeout = 20;
my $debug = 0;
sub devices {
open my $fh , '<' , "".$path.""
or die "Could not open file: ".$path." - $!\n";
flock($fh, LOCK_SH)
or die "Could not lock '".$fh."' - $!\n";
tie my %ini, 'Config::IniFiles', ( -file => "".$path."" )
or die "Error: IniFiles->new: @Config::IniFiles::errors";
close ($fh)
or die "Could not close '".$fh."' - $!\n";
my @keys = keys (%ini);
my %data = ();
my %final = ();
foreach my $hash (@keys) {
%data = clk_sync( $ini{$hash}{host},
$ini{$hash}{user},
$ini{$hash}{psw},
$ini{$hash}{port},
$hash );
@final{keys %data} = values %data;
}
return %final;
} # end sub complex
my %results = devices();
print Dumper(\%results);
sub clk_sync {
# alternative of shift my ($host,$user,$passwd,$port,$device) = (@_);
my $host = shift;
my $user = shift;
my $passwd = shift;
my $port = shift;
my $device = shift;
my %opts = ( passwd => $passwd,
port => $port,
user => $user );
my $ssh = Net::OpenSSH->new( $host, %opts );
$ssh->error and
die "Couldn't establish SSH connection: ". $ssh->error;
my ($stop, $pid_stop) = $ssh->open2pty("sudo -k; sudo service ntp stop")
or die "open2pty failed: " . $ssh->error . "\n";
my $expect_stop = Expect->init($stop);
$expect_stop->raw_pty(1);
$debug and $expect_stop->log_user(1);
$debug and print "waiting for password prompt\n";
$expect_stop->expect($timeout, ':')
or die "expect failed\n";
$debug and print "prompt seen\n";
$expect_stop->send("$passwd\n");
$debug and print "password sent\n";
$expect_stop->expect($timeout, "\n")
or die "bad password\n";
$debug and print "password ok\n";
my $result_stop = ();
while(<$stop>) {
# removing trailing characters such as \n
chomp $_;
# removing blank space before and after the string
$_ =~ s/^\s+|\s+$//g;
print "\$_: ".$_."\n";
$result_stop = $_;
}
my ($ntpd, $pid_ntpd) = $ssh->open2pty("sudo -k; sudo ntpd -gq")
or die "open2pty failed: " . $ssh->error . "\n";
my $expect_ntpd = Expect->init($ntpd);
$expect_ntpd->raw_pty(1);
$debug and $expect_ntpd->log_user(1);
$debug and print "waiting for password prompt\n";
$expect_ntpd->expect($timeout, ':')
or die "expect failed\n";
$debug and print "prompt seen\n";
$expect_ntpd->send("$passwd\n");
$debug and print "password sent\n";
$expect_ntpd->expect($timeout, "\n")
or die "bad password\n";
$debug and print "password ok\n";
my $result_ntpd = ();
while(<$ntpd>) {
# removing trailing characters such as \n
chomp $_;
# removing blank space before and after the string
$_ =~ s/^\s+|\s+$//g;
print "\$_: ".$_."\n";
$result_ntpd = $_;
}
my ($start, $pid_start) = $ssh->open2pty("sudo -k; sudo service ntp start")
or die "open2pty failed: " . $ssh->error . "\n";
my $expect_start = Expect->init($start);
$expect_start->raw_pty(1);
$debug and $expect_start->log_user(1);
$debug and print "waiting for password prompt\n";
$expect_start->expect($timeout, ':')
or die "expect failed\n";
$debug and print "prompt seen\n";
$expect_start->send("$passwd\n");
$debug and print "password sent\n";
$expect_start->expect($timeout, "\n")
or die "bad password\n";
$debug and print "password ok\n";
my $result_start = ();
while(<$start>) {
# removing trailing characters such as \n
chomp $_;
# removing blank space before and after the string
$_ =~ s/^\s+|\s+$//g;
print "\$_: ".$_."\n";
$result_start = $_;
}
my @send = ();
push (@send,$result_stop,$result_ntpd,$result_start);
chomp(@send);
my %hash_out = ( $device => [ $result_stop , $result_ntpd , $result_start ] );
#print Dumper(\%hash_out);
return %hash_out;
}
__END__
$_: * Stopping NTP server ntpd [ OK ]
$_: ntpd: time slew +0.000728s
$_: * Starting NTP server ntpd [ OK ]
$_: * Stopping NTP server ntpd [ OK ]
$_: ntpd: time slew -0.000542s
$_: * Starting NTP server ntpd [ OK ]
$VAR1 = {
'DEVICE 2' => [
'* Stopping NTP server ntpd [ OK ]',
'ntpd: time slew -0.000542s',
'* Starting NTP server ntpd [ OK ]'
],
'DEVICE 1' => [
'* Stopping NTP server ntpd [ OK ]',
'ntpd: time slew +0.000728s',
'* Starting NTP server ntpd [ OK ]'
]
};
</code>
</readmore>
<p>Configuration file (conf.ini)</p>
<readmore>
<code>
[DEVICE 1]
host = 127.0.0.1
user = username
psw = password
port = 22
[DEVICE 2]
host = 127.0.0.1
user = username
psw = password
port = 22
</code>
</readmore>
<div class="pmsig"><div class="pmsig-1069339">
Seeking for Perl wisdom...on the process of learning...not there...yet!
</div></div>
1101698
1101698