Ect0plasme
Ect0plasme

Reputation: 33

Store ouput over ssh using Net::SSH::Expect

student worker here. It's my first time working with perl, and I seem to have ran out of solutions, so I need your help!

I'm trying to store the ouput of a command on an HP Storeonce 3540 in a variable through the ssh module so I can extract some information I want to monitor:

Not sure if it's useful, but FYI the output is this:

system/show> performance

Service Set 1
 Storage Usage
   Current: xxxxx TB
   Maximum: xxxxx TB
 Throughput
   VTL Read: 0 MB/s
   VTL Write: 0 MB/s
   NAS Read: 0 MB/s
   NAS Write: 0 MB/s
   Catalyst Read: 0 MB/s
   Catalyst Write: 0 MB/s
 Replication
   Inbound: 0 MB/s
   Outbound: 0 MB/s
 Catalyst
   Inbound: 0 MB/s
   Outbound: 0 MB/s

Here's the code:

use Net::SSH::Expect;
use Capture::Tiny ':all';
use Backticks;
( ... )
  my $ssh = Net::SSH::Expect->new (
          host => $hp_host,
          password=> $hp_pwd,
          user => $hp_user,
          raw_pty => 1,
          timeout => 20
         );
  my $login_output = $ssh->login();
  if ($login_output !~ />/)
   {
    die "Login has failed. Login output was $login_output";
   }
  $ssh->send("system");
  $ssh->waitfor('\>\s*\z', 5) or die "Error #1-system";
  $ssh->send("show");
  $ssh->waitfor('\>\s*\z', 5) or die "Error #2-show";

Here I want to store the "performance" command's output. I have tried a bunch of combinations so here it goes:

1 - say '$ssh->send("performance")'->stdout;

gets me this error:

String found where operator expected at script_hpstoreonce.pl line 67, near "say '$ssh->send("performance")'" (Do you need to predeclare say?) syntax error at script_hpstoreonce.pl line xx, near "say '$ssh->send("performance")'"

2 - Backticks->run( '$ssh->send("performance")' ); print $stdout;

It does not print the output

3 - Every time I put the "$ssh-> " in front of the command I get this error:

ex: $ssh->Backticks->run( 'send("performance")' ); or $string = $ssh->tee('performance');

error: Can't locate object method "Backticks"/or("Tee")/ via package "Net::SSH::Expect" at script_hpstoreonce.pl line xx.

4 - $test = Backticks->stdout('performance'); print $stdout; or print $test;

error: Can't locate object method "Backticks" via package "Net::SSH::Expect" at script_hpstoreonce.pl line xx.

5 - I also tried to use the Capture::Tiny module but again:

$stdout = capture { $ssh->send("performance") }; print $stdout;

gets me this error:

Can't locate object method "capture" via package "Net::SSH::Expect" at script_hpstoreonce.pl line xx.

but

($stdout, $stderr) = capture {$ssh->send("performance")}; print $stdout;

or

$stdout = capture_stdout{$ssh->exec("performance")}; print $stdout;

or

my($stdout, $stderr, $exit) = $ssh->send('performance'); print $stdout;

or

$stdout = $ssh->capture('performance'); print $stdout;

Does not print anything when I run the script.

6 - Same thing goes for Tee:

$string = tee {$ssh->send("performance")}; print $string;

Doesn't print anything

Since the same errors are popping up even when I use different modules, I understand that I'm probably missing something due to my lack of knowledge of the language and my lack of experience, but I can't seem to find what's wrong here. Is the problem in the $ssh-> protocole??

Thank you

Upvotes: 3

Views: 930

Answers (2)

popeonhabbo123
popeonhabbo123

Reputation: 71

If you want to save the output of the commands in 1 report try this

use Net::SSH::Expect
use strict;
use warnings;

my $stdout = $ssh->exec($command);
my $stdout2 = $ssh->exec($command);

my $filename = 'report.txt';
open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
print $fh "$stdout" . "$stdout2";
close $fh;
print "done\n";

This should Print both variables into a .txt report

Upvotes: 0

jwal
jwal

Reputation: 660

Perl will mostly collect all sorts of output without need of additional packages. It's only special cases where you need something extra. In this case just the Net::SSH::Expect would be enough.

I don't have Net::SSH::Expect on my system however it seems like what you need is:

$ssh->send("find /");   # using send() instead of exec()
my $line;
while ( defined ($line = $ssh->read_line()) ) {
  print $line . "\n";  
}

For something as short as what you have shown I'd be inclined to skip the complexity of send and read_line and just go with exec.

my $who = $ssh->exec("who");
print ($who);

Upvotes: 2

Related Questions