Reputation: 121
I want to SSH to a server and execute a simple command like "id" and get the output of it and store it to a file on my primary server. I do not have privileges to install Net::SSH which would make my task very easy. Please provide me a solution for this. I tried using back-ticks but I am not able to store the output on the machine from which my script runs.
Upvotes: 12
Views: 109869
Reputation: 1665
use warnings;
use strict;
use Net::SSH2;
sub is_sshalive;
my $host = "ip"; # use the ip host to connect
my $user = "UNAME"; # your account
my $pass = "PASSWD"; # your password
my $cmd;
my $ssh2 = Net::SSH2->new();
$ssh2->debug(1);
if ($ssh2->connect($host)) {
#if ($ssh2->auth_password($user,$pass)) {
if ($ssh2->auth_keyboard($user,$pass)) {
print "\n Executing command...\n";
$cmd = "ls";
print " ==> Running $cmd\n";
if(is_sshalive($ssh2) == 1) {
print "\nSSH connection died";
exit 1;
} else {
run_testsuite($cmd, $ssh2);
}
} else {
warn "ssh auth failed.\n";
exit 1;
}
} else {
warn "Unable to connect Host $host \n";
exit 1;
}
print "test passed done 0\n";
sub run_testsuite {
my $cmd = $_[0];
my $ssh2 = $_[1];
my $chan2 = $ssh2->channel();
$chan2->shell();
print $chan2 "$cmd \n";
print "LINE : $_" while <$chan2>;
$chan2->close;
return 0;
}
sub is_sshalive {
my $ssh2 = $_[0];
if ($ssh2->poll(1000) == 0) {
return 0; # passed
} else {
return 1; #failed
}
}
Upvotes: 0
Reputation: 7259
The best way to run commands remotely using SSH is
$ ssh user@host "command" > output.file
You can use this either in bash or in perl. However, If you want to use perl you can install the perl modules in your local directory path as suggested by brian in his comment or from Perl FAQ at "How do I keep my own module/library directory?". Instead of using Net::SSH I would suggest to use Net::SSH::Perl with the below example.
#!/usr/bin/perl -w
use strict;
use lib qw("/path/to/module/");
use Net::SSH::Perl;
my $hostname = "hostname";
my $username = "username";
my $password = "password";
my $cmd = shift;
my $ssh = Net::SSH::Perl->new("$hostname", debug=>0);
$ssh->login("$username","$password");
my ($stdout,$stderr,$exit) = $ssh->cmd("$cmd");
print $stdout;
Upvotes: 16
Reputation: 1778
I know this is a very old thread, but since I encounter the same problem I found another useful solution in case that someone is using Linux.
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $host = $ARGV[0];
my $port = $ARGV[1];
my $cmd = $ARGV[2];
my @output = readpipe( "ssh -p ".
$port." ".
$host." ".
$cmd."" );
chomp @output;
print Dumper \@output;
__END__
perl sample.pl 127.0.0.1 22 "which perl"
Ubuntu 16.04.1 LTS
$VAR1 = [
'/usr/bin/perl'
];
This assumes that you have configured ssh-keys so no user input will be required. I did not want to have hard coded values this is the best way for me that worked the best. I am using readpipe to achieve that.
Hope this helps to have a solution in case of not hard coding.
Upvotes: 0
Reputation: 20391
I had a similar issue, and after much searching I've found a simple option. I used qx()
and ran the ssh commands like I normally would. The catch is I had to capture both stderr and stdout.
The following is an example of what I used:
my $output = qx(ssh root\@$curIP python -V 2>&1);
It runs the python -V
command, which outputs the version info to stderr
. In this example, my ip address was stored in the $curIP
variable. Lastly, the 2>&1
helps capture both stdout and stderr. I did not specify a password, as I have key exchanges setup. Hope this helps.
Upvotes: 1
Reputation: 21
or, assuming host keys are present and you want to do something with the command ouput ...
open(SSH,"/usr/bin/ssh you\@server ps aux |") or die "$!\n";
while (<SSH>) {
# do stuff with $_
}
close SSH;
Upvotes: 2
Reputation: 7987
If you're using backticks try this:
my @output = `ssh [email protected] "which perl"`;
print "output: @output";
This is only useful if you have a publickey that the above command won't prompt for password.
Upvotes: 1
Reputation: 47
Assuming that you're in an environment like me where you can't add additional modules and you can't create an Identity file, then you can use this script as a starting point.
If you can set up ssh keys then simply use the backticks command already posted, although you might need the -i option
#!/usr/bin/perl
use warnings;
use strict;
use Expect;
use Data::Dumper;
my $user = 'user';
my $pw = 'password';
my $host = 'host';
my $cmd = 'id';
my $exp = new Expect;
$exp->log_file("SSHLOGFILE.txt");
$exp->log_stdout(0);
$exp->raw_pty(1);
my $cli = "/usr/bin/ssh $user\@$host -o StrictHostKeyChecking=no -q $cmd";
$exp->spawn($cli) or die "Cannot spawn $cli: $!\n";
$exp->expect(5,
[ qr /ssword:*/ => sub { my $exph = shift;
$exph->send("$pw\n");
exp_continue; }] );
my $read = $exp->exp_before();
chomp $read;
print Dumper($read);
$exp->soft_close();
Upvotes: 0
Reputation: 64909
You can always install modules locally, and that is the method you should look into; however, you should be able to get away with
#!/usr/bin/perl
use strict;
use warnings;
my $id = qx/ssh remotehost id 2>&1/;
chomp $id;
print "id is [$id]\n"
Upvotes: 8
Reputation: 2295
If you have ssh host keys setup you can simply run the ssh system command and then specify the command to run on the machine after that. For example:
`ssh [email protected] id`
You should be able to chomp/store that output.
Upvotes: 1