AnyEvent-SSH2
view release on metacpan or search on metacpan
lib/AnyEvent/SSH2.pm view on Meta::CPAN
my $cmgr = $ssh->channel_mgr;
my $channel = $ssh->_session_channel;
$channel->open;
$channel->register_handler(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, sub {
my($channel, $packet) = @_;
## Experimental pty support:
if ($ssh->{config}->get('use_pty')) {
$ssh->debug("Requesting pty.");
my $packet = $channel->request_start('pty-req', 0);
my($term) = $ENV{TERM} =~ /(\w+)/;
$packet->put_str($term);
my $foundsize = 0;
if (eval "require Term::ReadKey") {
my @sz = Term::ReadKey::GetTerminalSize($ssh->sock);
if (defined $sz[0]) {
$foundsize = 1;
$packet->put_int32($sz[1]); # height
$packet->put_int32($sz[0]); # width
$packet->put_int32($sz[2]); # xpix
$packet->put_int32($sz[3]); # ypix
}
}
if (!$foundsize) {
$packet->put_int32(0) for 1..4;
}
# Array used to build Pseudo-tty terminal modes; fat commas separate opcodes from values for clarity.
my $terminal_mode_string;
if(!defined($ssh->{config}->get('terminal_mode_string'))) {
my @terminal_modes = (
5 => 0,0,0,4, # VEOF => 0x04 (^d)
0 # string must end with a 0 opcode
);
for my $char (@terminal_modes) {
$terminal_mode_string .= chr($char);
}
}
else {
$terminal_mode_string = $ssh->{config}->get('terminal_mode_string');
}
$packet->put_str($terminal_mode_string);
$packet->send;
}
my $r_packet = $channel->request_start("exec", 0);
$r_packet->put_str($cmd);
$r_packet->send;
});
my($exit);
$channel->register_handler(SSH2_MSG_CHANNEL_REQUEST,
_make_input_channel_req(\$exit));
my $h = $ssh->{client_handlers};
my($stdout, $stderr);
if (my $r = $h->{stdout}) {
$channel->register_handler("_output_buffer",
$r->{code}, @{ $r->{extra} });
}
else {
$channel->register_handler("_output_buffer", sub {
$stdout .= $_[1]->bytes;
});
}
if (my $r = $h->{stderr}) {
$channel->register_handler("_extended_buffer",
$r->{code}, @{ $r->{extra} });
}
else {
$channel->register_handler("_extended_buffer", sub {
$stderr .= $_[1]->bytes;
});
}
$ssh->debug("Entering interactive session.");
$channel->{cb} = sub {
$cb->($ssh, $stdout, $stderr);
}
}
sub break_client_loop { $_[0]->{ek_client_loopcl_quit_pending} = 1 }
sub restore_client_loop { $_[0]->{_cl_quit_pending} = 0 }
sub _quit_pending { $_[0]->{_cl_quit_pending} }
sub client_loop {
my $ssh = shift;
return unless scalar @{$ssh->{events}{cmd}} > 0;
$ssh->emit('cmd');
$ssh->{_cl_quit_pending} = 0;
# åææé¢é
my $cmgr = $ssh->channel_mgr;
# å¤çæ¯ä¸ªé¢éçäºä»¶
my $h = $cmgr->handlers;
$ssh->event_loop($cmgr, $h);
}
sub event_loop {
my ($ssh, $cmgr, $h, $cb) = @_;
return $ssh->client_loop if $ssh->_quit_pending;
while (my $packet = Net::SSH::Perl::Packet->read_poll($ssh)) {
if (my $code = $h->{ $packet->type }) {
$code->($cmgr, $packet);
}
else {
$ssh->debug("Warning: ignore packet type " . $packet->type);
}
}
return $ssh->client_loop if $ssh->_quit_pending;
$cmgr->process_output_packets;
# 妿å¤çå®äº. å
³æææçè¿æ¥
# 乿以å¨è¿è¿è¡è¿ä¸ªæä½æ¯å 为主 channel ä¹éè¦æä½
for my $c (@{ $cmgr->{channels} }) {
next unless defined $c;
if ($c->{wfd} &&
$c->{extended}->length == 0 &&
$c->{output}->length == 0 &&
$c->{ostate} == CHAN_OUTPUT_WAIT_DRAIN ) {
$c->obuf_empty;
}
# ä¸é¢ obuf_empty ä¼ç» ostate åæ CHAN_OUTPUT_CLOSED
# ä¸é¢è¿ä¸ªå°±ä¼åå
³éç»è¿ç¨
if ($c->delete_if_full_closed) {
defined $c->{cb} ? $c->{cb}->() : '';
$cmgr->remove($c->{id});
}
}
my $oc = grep { defined } @{ $cmgr->{channels} };
return $ssh->client_loop unless $oc > 1;
my $cv = AE::cv sub {
lib/AnyEvent/SSH2.pm view on Meta::CPAN
sub channel_mgr {
my $ssh = shift;
unless (defined $ssh->{channel_mgr}) {
$ssh->{channel_mgr} = Net::SSH::Perl::ChannelMgr->new($ssh);
}
$ssh->{channel_mgr};
}
sub _read_version {
my $ssh = shift;
my $line = shift;;
my $len = length $line;
unless(defined($len)) {
next if $! == EAGAIN || $! == EWOULDBLOCK;
croak "Read from socket failed: $!";
}
croak "Connection closed by remote host" if $len == 0;
croak "Version line too long: $line"
if substr($line, 0, 4) eq "SSH-" and length($line) > 255;
croak "Pre-version line too long: $line" if length($line) > 4*1024;
if (substr($line, 0, 4) ne "SSH-") {
$ssh->debug("Remote version string: $line");
}
return $line;
}
sub sock { $_[0]->{session}{sock} }
1;
__END__
=pod
=encoding utf8
=head1 NAME
AnyEvent::SSH2 - åºäº AnyEvent ç SSH2 çéé»å¡äºä»¶é©±å¨çå®ç°
=head1 SYNOPSIS
对å¤å°ä¸»æº, å¹¶è¡çè¿ç¨æ§è¡ä¸äºå½ä»¤.
use AE;
use AnyEvent::SSH2;
my $ssh1 = AnyEvent::SSH2->new(
'ip',
user => 'root',
pass => 'pass',
);
my $ssh2 = AnyEvent::SSH2->new(
'ip'
user => 'root',
pass => 'pass',
);
my $cv = AE::cv;
$cv->begin;
$ssh1->send('sleep 5;hostname' => sub {
my ($ssh, $stdout, $stderr) = @_;
print "$stdout";
$cv->end;
})->connect;
$cv->begin;
$ssh2->send('sleep 1;hostname' => sub {
my ($ssh, $stdout, $stderr) = @_;
print "$stdout";
$cv->end;
})->connect;
$cv->recv;
对åä¸ä¸ªä¸»æº, å¹¶è¡çæ§è¡å¤æ¡å½ä»¤...注æé¡ºåºå¹¶ä¸åºå®, ä»»ä½ä¸ä¸ªå½ä»¤å
æ§è¡å®é½ä¼å
åè°.
use AnyEvent::SSH2;
my $ssh = AnyEvent::SSH2->new(
'ip'
user => 'root',
pass => 'pass',
);
my $cv = AE::cv;
$cv->begin;
$ssh->send('sleep 5; echo 5' => sub {
my ($ssh, $stdout, $stderr) = @_;
print "$stdout";
$cv->end;
});
$cv->begin;
$ssh->send('sleep 1; echo 1 ; uptime' => sub {
my ($ssh, $stdout, $stderr) = @_;
print "$stdout";
$cv->end;
});
$ssh->connect;
$cv->recv;
æè
ä½ å¯è½æ³æä¸å®å±æ¬¡, æ ¹æ®å䏿¡å½ä»¤çæ¡ä»¶æ¥æ§è¡æå®çå½ä»¤.
my $cv = AE::cv;
$ssh->send('sleep 5; echo 5' => sub {
my ($ssh, $stdout, $stderr) = @_;
print "$stdout";
$ssh->send('sleep 1; echo 1 ; uptime' => sub {
my ($ssh, $stdout, $stderr) = @_;
print "$stdout";
$cv->send;
});
});
$ssh->connect;
$cv->recv;
=head1 DESCRIPTION
è¿ä¸ªæ¨¡åæ¯åºäº Net::SSH::Perl å®ç°çå¨ AnyEvent ä¸çäºä»¶é©±å¨çæ¯æ. 并䏿¯ä½¿ç¨ç Fork çå®ç° (non-fork), è¿æ¯åºäº socket çåçäºä»¶é©±å¨å®ç°.
å¯ä»¥åæ¶å¼æ¥çè¿æ¥å¤ä¸ªä¸»æºè¿è¡æä½. å¹¶ä¸ä¹å¯ä»¥æ¯æåæ¶å¯¹ä¸ä¸ªä¸»æºåæ¶æ§è¡å¤æ¡å½ä»¤ä¸æ ¹æ®åé¢ç»æç¶å卿§è¡æå®å½ä»¤.
=head1 屿§
é»è®¤å¯¹è±¡ new çæ¶åéè¦æä¾è¿æ¥ç主æºå°å. æ¬å¯¹è±¡ç屿§ç»§æ¿ææç L<Net::SSH::Perl> ç屿§. å¹¶å®ç°äºä¸åè¿äº
=head2 user
æä¾ç¨äºè¿ç¨è¿æ¥çç¨æ·å. 妿䏿ä¾ä¼é»è®¤ä½¿ç¨å½åç¨æ·.
=head2 pass
æä¾ç¨äºè¿ç¨è¿æ¥çå¯ç . 乿¯æ key æ¹å¼è®¤è¯. éè¦æå®å¦ä¸å±æ§
identity_files => ['/root/.ssh/id_rsa'],
options => [
'PubkeyAuthentication yes',
'PasswordAuthentication no', # å¯è½ä½ æ³å
³æå¯ç 认è¯
],
=head1 æ¹æ³
æ¬å¯¹è±¡ææ¯æçæ¹æ³å¦ä¸
=head2 send
è¿ä¸ªéè¦æä¾ä½ è¦ç»è¿ç¨æ§è¡çå½ä»¤å为第ä¸ä¸ªåæ°, 第äºä¸ªåæ°æ¯å½ä»¤æ§è¡å®çåè°å½æ°.
åè°å½æ°ç第äºä¸ªå第ä¸ä¸ªåæ°ä¼å«ä¼æ¯å½ä»¤æ§è¡çæ åè¾åºåæ åé误.
æ¬æ¹æ³å¯ä»¥éå¤è®¾ç½®, é½ä¼ä¸æ¬¡æ§åç»è¿ç¨ä¸»æºæ§è¡. æä»¥æ§è¡å®ä¼æ ¹æ®æ§è¡ç»æçé度, ä¼ç«å³è¿åå¹¶è°ç¨åè°.
=head2 connect
å½ä¸é¢çå½ä»¤å®ä¹å®äº, å¯ä»¥è°ç¨ connect æ¹æ³æ¥è¿è¡æ´ä¸ªäºä»¶.
=head1 SEE ALSO
L<AnyEvent>, L<Net::SSH::Perl>
=head1 AUTHOR
æ¶å¯ fukai <iakuf@163.com>
=cut
( run in 1.513 second using v1.01-cache-2.11-cpan-39bf76dae61 )