首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenSSH POE会话卡住

OpenSSH POE会话卡住
EN

Stack Overflow用户
提问于 2017-12-15 17:58:42
回答 1查看 75关注 0票数 0

我使用POE::Component::OpenSSH和每个设备的单独POE::Session对我们网络上的300多个无线电设备进行非阻塞ssh操作。我的脚本是工作形式,但有些设备没有配置正确的密码(为了简单起见,我们为所有设备保留相同的密码,因此使用相同的密码进入每个设备)。有时,工程师会犯错误,安装带有非标准ssh密码的设备.在这种情况下,如果OpenSSH无法进行身份验证,POE::Session就会卡住(_stop永远不会被调用,脚本也不会退出)。我知道这不是一个纯粹的程序问题。我们每天在网络上安装很少的设备,我不能指望我们的工程师每次都输入正确的密码。因此,即使我更正了我们现有设备上的密码,将来也不可避免地会有一个带有错误密码的设备,这会导致我的进程挂起。

我可以做$内核->停止,但我不喜欢那样。我希望本届会议能够自我澄清。是否有一种方法可以使用观察者会话清除POE::Component::OpenSSH在会话中使用的资源/服务?任何帮助都是非常感谢的。请看下面的代码。

代码语言:javascript
复制
use strict;
use warnings;
use POE;
use POE::Component::OpenSSH;
use POE::Component::Client::Ping;
use Data::Dumper;

my $domain = shift;
my @args = ($domain);
my $session = POE::Session->create(
        args => \@args,
        inline_states => {
                _start => \&start,
                configcapture => \&configcapture,
                activecapture => \&activecapture,
                detectdfs => \&dfs,
                pong => \&pingresult,
                handlerror => \&handlerror,
                _stop   => \&stop,
        },
);

POE::Kernel->run();
exit;

sub start {
        $_[KERNEL]->sig( DIE => 'sig_DIE' );
        print "STARTING ... for $_[ARG0] \n";
        $_[HEAP]{'domain'} = $domain;

        my $ssh = POE::Component::OpenSSH->new(
                args => ['user@'.$domain.':6022', passwd => '123' ],
        );

        $ssh->capture({event => 'configcapture', timeout => 2},
                      'cat /tmp/system.cfg | grep radio.1.freq');
        $ssh->capture({event => 'activecapture', timeout => 2},
                      '/usr/www/status.cgi');
        $_[KERNEL]->delay(detectdfs => 5);
}

sub configcapture {
        $_[HEAP]{'configfreq'} = $_[ARG0]{'result'}[0];
}

sub activecapture {
        $_[HEAP]{'activefreq'} = $_[ARG0]{'result'}[0];
}

sub dfs {
        if(defined($_[HEAP]{'configfreq'}) &&
           defined($_[HEAP]{'activefreq'})) {
                print "CONFIG: $_[HEAP]{'configfreq'}\n";
                print "ACTIVE: $_[HEAP]{'activefreq'}\n";
        }
}

sub stop {
        my ($self, $output) = @_;
        print "Ending Session Here \n";
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-22 10:54:18

谢谢你的留言。不过我自己找到了解决办法。在构造POE::Component::OpenSSH时,我必须添加timeout,以便它为每个会话调用_stop事件。但剧本仍未退出。

由于POE:: component ::OpenSSH使用POE::Component::Generic生成阻塞Net::OpenSSH进程作为POE会话,因此我只需调用POE::Component::Generic组件对象的shutdown方法,该对象被卡住(密码错误),所有会话结束时都干净,脚本退出。

请见以下解决办法:

代码语言:javascript
复制
$_[HEAP]{'ssh'} = POE::Component::OpenSSH->new(
                args => [user@domain, passwd => '123', timeout => 180, async => 1, master_opts => [-o => "StrictHostKeyChecking=no"]],
        );

然后在_stop

代码语言:javascript
复制
my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
delete $heap->{wheel};
$kernel->alias_remove($heap->{alias});
$kernel->alarm_remove_all();
$_[HEAP]{'ssh'}->object->shutdown;
delete($_[HEAP]{'ssh'});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47837582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档