• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 707
  • Last Modified:

NET::SSH2 Terminates Unexpectedly

My goal is to write a Perl script which connects to a remote server using the SSH2 package.  The script runs a command which generates a list of all files and their md5sum.  The problem is occasionally the script will terminate unexpectedly.

 
#!/usr/bin/perl

use Net::SSH2;

$ssh2 = Net::SSH2->new();

$ssh2->connect('asdfasdfas.com') or die $!;
$ssh2->auth_password('user','pass') or die "Unable to login $@ \n";
$ssh2->debug(0);

$chan2 = $ssh2->channel();
$chan2->blocking(0);
$chan2->shell();
print $chan2 "bash ~/md5xml\n";
print "LINE : $_" while <$chan2>;
$chan2->close;

print 'done...';

Open in new window

nothing?john@sporkit.com-> ./ssh_web_sync.pl
LINE : MD5 (./.cshrc) = 7cd795d80cbc7cb24a96828992a4897e
LINE : MD5 (./.login) = 753b51225e21863dd2278ba0753d4bc4
LINE : MD5 (./.mailrc) = d0bbf8bf09a43ffdbc902bcbdc08304f
LINE : MD5 (./.profile) = 5d598ba6fb89ec78c77128b560ce4d78
LINE : MD5 (./.rhosts) = 8487c7b9ad8bde81f31377610ff7397d
LINE : MD5 (./.mail/new/1288302002.13058_2.brunner.asdffdsa.com) = 8dc6c40e37b91ebe4eb4c22b0c42aaa2

Open in new window


Most of the time I will get about 50 results back, but sometimes I'll get as little as 6 lines.  The remote script being called is a simple find and exec command.

find ./ -type f -exec md5 {} \;

My goal is to grab an md5 list of files on the remote machine so I can compare is with a local list.

Thanks

I've also tried this with NET:SSH and NET:OPENSSH, both of which failed to even open a connection.
0
sporkit150
Asked:
sporkit150
  • 3
  • 2
1 Solution
 
Justin MathewsCommented:
Try changing:

print "LINE : $_" while <$chan2>;

To:

<$chan2>, print "LINE : $_" while !eof($chan2);

0
 
sporkit150Author Commented:
Now the script appears to hang for a minute or two then dumps this code every two minutes or so.
john@sporkit.com-> ./ssh_web_sync.pl
LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LIN

Open in new window

I added an exit command to jump out of the shell when run and that eventually brings me to the "done..." print statement at the end.  It appears as if were close but $_ might not be getting the data we need from the buffer.
 
$chan2->shell();
print $chan2 "bash ~/md5xml\n";
print $chan2 "exit\n";
<$chan2>, print "LINE : $_" while !eof($chan2);
$chan2->close;
print 'done...';

Open in new window

john@sporkit.com-> ./ssh_web_sync.pl
LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LINE : LI......................E : LINE : LINE : done...

Open in new window

0
 
Justin MathewsCommented:
Assign it to a variable and print as:

$l=<$chan2>, print "LINE : $l" while !eof($chan2);
0
 
sporkit150Author Commented:
FINALLY... I think that did the trick.  I had to remove the LINE statement statement as it was adding extra returns while printing.  Here is my final output.

 
#!/usr/bin/perl

use Net::SSH2;

$ssh2 = Net::SSH2->new();
$ssh2->connect('asdfasdf.com') or die $!;
$ssh2->auth_password('asdfasdf','asdfasdf') or die "Unable to login $@ \n";
$ssh2->debug(0);

$chan2 = $ssh2->channel();
$chan2->blocking(0);
$chan2->shell();
print $chan2 "bash ~/md5xml\n";
print $chan2 "exit\n";
$l=<$chan2>, print "$l" while !eof($chan2);
$chan2->close;

print 'done...';

Open in new window


Could you also explain how this print statement is working?  It says something like, while not end of file from channel2 print "LINE: $l".  What is up with the comma though?  Could you write it like...

 
$l=<$chan2>;
print "LINE : $l" while !eof($chan2);

Open in new window

0
 
Justin MathewsCommented:
No. Because reading also should inside the while loop. Otherwise it will always print one value and the loop will never end since it never reads again after the first read. That is why it should be:

$l=<$chan2>, print "$l" while !eof($chan2);

OR

while (!eof($chan2))
{
   $l = <$chan2>;
   print "$l";
}

OR just

print <$chan2> while !eof($chan2);

0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now