Created
July 29, 2012 13:51
-
-
Save marshyon/3198938 to your computer and use it in GitHub Desktop.
test and demonstrate the use of Net::SSH::Expect Perl module to connect via SSH using key authentication, to known and unknown hosts, running commands and processing captured standard output from those commands
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use warnings; | |
use strict; | |
use Date::Parse; | |
use Net::SSH::Expect; | |
use POSIX qw(strftime); | |
# set to a known host on your network | |
# that has not been ssh shell connected | |
# to by this user before | |
my $known_host = "some_server_we_know"; | |
# invoke a Net::SSH::Expect object | |
my $ssh = Net::SSH::Expect->new ( | |
host => "localhost", | |
user => 'marshyon', | |
raw_pty => 1 | |
); | |
# as we have already set up an SSH key pair and | |
# loaded it with 'ssh-add' and tested the connection | |
# manually, we need no password to connect to the | |
# target server .... | |
$ssh->run_ssh() or die "SSH process couldn't start: $!"; | |
# we over-ride the current console prompt, likely set by | |
# .bashrc or system wide bash or profile with one that we | |
# know has no 'escape characters' ( e.g. colors ) and that | |
# we can use later to pattern match returned output | |
my $set_promt_cmd = q(PS1='console:\h \$ '); | |
$ssh->exec($set_promt_cmd); | |
# get the hosname of the host we are connected to | |
my $hostname = $ssh->exec("hostname"); | |
$hostname=~ m{(.+?)\nconsole:}msx; | |
# using the custom prompt we set earlier, the hostname | |
# can be accurately extracted from captured stdout | |
print "hostname is [$1]\n"; | |
# now we can ssh to a server that exists but we | |
# have not visited before | |
my $ssh_session = $ssh->exec("ssh $known_host"); | |
# testing the returned output we can see that this is the | |
# case and respond to not accept and record the key from | |
# this connection | |
if( $ssh_session =~ m{Are you sure you want to continue}i ) { | |
print "we have not seen this one before,....\n"; | |
$ssh->exec("no"); | |
} | |
# next we try to connect to a server that does not | |
# exist or is otherwise off line | |
$ssh_session = $ssh->exec("ssh no_server_anywhere"); | |
if( $ssh_session =~ m{Could not}i ) { | |
print ">>>\n$ssh_session\n"; | |
print "this one seems like its a gonner...\n"; | |
} | |
# on the current server connection we now run a command to | |
# list the current directory | |
# nb: ls will 'colourise' it's output unless we use the switch | |
# '--color=never' - colours will contain escape characters | |
# that will goose some pattern matching from working | |
# properly | |
my $listing_cmd = 'ls --color=never -al'; | |
my $listing = $ssh->exec($listing_cmd); | |
$listing =~ m{(.+)\nconsole:}msx; | |
print ">>\n$1\n.................\n"; | |
# lastly, lets do something useful with the listing we just | |
# got back, namely extract file name, file date when last modified | |
# and the size of each file | |
# file | |
my @file_listing = split(/\n/, $listing); | |
foreach my $file_list (@file_listing) { | |
# here is an example of what we are trying to match .... | |
# -rw------- 1 marshyon marshyon 2089 Jul 29 13:57 .bash_history | |
# here is the regex in an 'if' with comments ( the x switch in ... match {} msx .. | |
# lets us add comments to the regular expression ) .... | |
if( $file_list =~ m{ | |
\S+ \s+ \d+ \s+ # non space(s), space(s), digit(s), space(s) | |
marshyon \s+ # literal string, space(s) | |
marshyon \s+ # literal string, space(s), | |
( \d+ ) \s+ # capture digit(s) into $1 followed by space(s) | |
(.+?) \s+ # one or more characters non greedy captured to $2, space(s) | |
(\S+) $ # non space(s) captured to $3 to end of line | |
}msx ) { | |
my ($size, $date_str, $file) = ($1, $2, $3); | |
# using Date::Parse modules function, parse date string | |
my $epoch = str2time($date_str); | |
my $date_formatted = strftime "%Y-%m-%d %H:%M", localtime; | |
print "size[$size] epoch[$epoch] date_formatted[$date_formatted] file[$file]\n"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment