使用Expect.pm以未知顺序匹配多个模式

时间:2013-07-18 09:49:19

标签: perl expect

我目前正在开发一个自动配置服务器的脚本。我使用Expect.pm模块与服务器进行交互,但现在我遇到了一个我不知道如何解决的问题。

我要做的是send向服务器发出命令,列出当前安装在服务器上的设备,然后检查某些项目是否在该列表中。问题是列表是随机排列的,所以我不知道我应该首先考虑哪个项目。

我想要完成的是查找所有项目,然后在匹配所有项目后退出expect电话。请记住,每个服务器都有自己的一组设备,我必须匹配的设备数量可能会有所不同,因此解决方案必须解决一般情况。有没有办法用Expect.pm完成此任务?我已经尝试了一段时间,似乎无法找到一个好的解决方案...

提前致谢!

/ Haso

编辑:我找到了解决方案

我编写了一个函数,它将为expect调用构造参数数组,然后进行调用。在这种情况下,引用$self是我自己定义的对象,但$self->{_expect}是期​​望对象。

sub match_all {
    my $self = shift;
    my $timeout = shift;
    my @patterns = @_;

    my $pattern_count = @patterns;
    my $match_count = 0;

    #Function that is called when a pattern is matched
    sub match{
        my $exp = shift;
        my $mc_ptr = shift;
        my $pc_ptr = shift;
        $$mc_ptr++;
        if($$mc_ptr != $$pc_ptr) {
            #Set the accumelator to the before and after string,
            #effectivly cutting away the matched substring.
            my $before = $exp->before();
            my $after = $exp->after();
            $exp->set_accum($before.$after);
            exp_continue_timeout;
        }
    }

    #Build the array of patterns for the expect call
    my @exp_patterns;
    foreach my $pattern (@patterns) {
        push @exp_patterns, [$pattern, \&match, \$match_count, \$pattern_count];
    }

    #Set notransfer to True in order to manipulate
    #the accumelator on my own during this function
    $self->{_expect}->notransfer(1);
    $self->{_expect}->expect($timeout, @exp_patterns);
    $self->{_expect}->notransfer(0);

    return $match_count == $pattern_count;
}

1 个答案:

答案 0 :(得分:0)

  

设备集

这是一个神奇的词。使用Set::Scalar

如果$expect_devices->is_subset($known_devices),您就有了“匹配”。