Created
May 29, 2012 16:19
-
-
Save melo/2829330 to your computer and use it in GitHub Desktop.
A sample Net::SSH2 command line talking to a inline remote perl script
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 v5.14; | |
use strict; | |
use Net::SSH2; | |
my $user = shift(@ARGV) || usage('Missing user'); | |
my $host = shift(@ARGV) || usage('Missing host'); | |
my $port = shift(@ARGV) || 22; | |
## Connect and authenticate using ssh-agent | |
my $ssh2 = Net::SSH2->new(); | |
$ssh2->connect($host, $port) or die $!; | |
$ssh2->auth_agent($user); | |
die "Failed to autenticate: $!" unless $ssh2->auth_ok; | |
say "Connected to '$host' as '$user'"; | |
## Enable compression, couldn't get it work with my libssh2 though... | |
for my $dir ('COMP_CS', 'COMP_SC') { | |
$ssh2->method($dir, 'zlib'); | |
say "Compression $dir: ", $ssh2->method($dir); | |
} | |
## Start a channel with a remote perl, send our remote controller | |
## program | |
my $chan = $ssh2->channel(); | |
$chan->exec('/usr/bin/perl'); | |
my $perl_program = <<'EOR'; | |
$|++; | |
print `uname -a`; | |
print "Start typing remote commands, type ^D to exit\n"; | |
while (<>) { | |
print "GOT $_"; | |
} | |
print "Bye now...\n"; | |
__END__ | |
EOR | |
$chan->write($perl_program); | |
$chan->flush; | |
## Read remote controller program header | |
_read_chan($chan); | |
## wait for local commands, and send them to the remote side, print | |
## remote output | |
{ | |
local @ARGV; | |
while (<>) { | |
$chan->write($_); | |
_read_chan($chan); | |
} | |
} | |
## On local ^D, send EOF to remote side, read goodbye message | |
$chan->send_eof; | |
_read_chan($chan); | |
## close channel and disconnect | |
$chan->close; | |
$ssh2->disconnect; | |
## _read_chan: read all input from chan, dump it to STDOUT | |
## Hack time! Here be dragons | |
sub _read_chan { | |
my ($chan) = @_; | |
## we switch to non-blocking and sleep between retries because it | |
## would fail to read anything with a blocking call... Still trying | |
## to find out why the blocking call would not read nothing. | |
$chan->blocking(0); | |
my $done; | |
while (1) { | |
my $in; | |
while (my $bytes = $chan->read($in, 1024)) { | |
$in =~ s/^/> /gm; | |
print $in; | |
$done++; | |
} | |
## We leave after one sucessful read, this could be improved... | |
last if $done; | |
select(undef, undef, undef, .25); ## sleep 50 ms | |
} | |
$chan->blocking(1); | |
} | |
sub usage { | |
my ($msg) = @_; | |
say STDERR "FATAL: $msg" if $msg; | |
say STDERR "Usage: ssh.pl user host [port]"; | |
exit(1); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment