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.
-
8Are you sure you don't have the privileges you need to install Net::SSH? http://www.shadowcat.co.uk/blog/matt-s-trout/but-i-cant-use-cpan/ – Quentin May 17 '10 at 12:34
-
There is plenty of information about installing Perl modules in your own space. It's even on Stackoverflow: http://stackoverflow.com/questions/251705/how-can-i-use-a-new-perl-module-without-install-permissions – brian d foy May 18 '10 at 00:16
-
11While I realize this is an old question I feel I have a need to comment. Why are most programmers dumb founded when other programmer's ask for help because they are not allowed to use open source code and then comment back about how easy it is to install the code and use it. There are still companies that do not allow their programmers to use external code unless it goes under rigorous testing for functionality, performance, security, etc. My company happens to be one just like that. They prefer you to reinvent the wheel than use outside code and do everything they can to prevent its use. – Matt Pascoe Sep 27 '12 at 20:36
-
Salman writes: I do not have the privileges. This suggests a file permission issue, not a company policy issue. The comments explain how the file permission issues are easy to overcome. – reinierpost Oct 12 '16 at 09:52
9 Answers
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;

- 46,058
- 19
- 106
- 116

- 7,049
- 6
- 49
- 68
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"

- 64,182
- 22
- 135
- 226
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;

- 21
- 1
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.

- 564
- 3
- 12

- 19,579
- 27
- 94
- 160
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 user@remoteserver.domain.com id`
You should be able to chomp/store that output.

- 2,247
- 1
- 21
- 33
If you're using backticks try this:
my @output = `ssh root@1.1.1.1 "which perl"`;
print "output: @output";
This is only useful if you have a publickey that the above command won't prompt for password.

- 7,298
- 1
- 57
- 65
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
}
}
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();

- 47
- 2
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.

- 1,618
- 4
- 28
- 49