Perl 打印expect输出而不调用变量

Perl 打印expect输出而不调用变量,perl,automation,expect.pm,Perl,Automation,Expect.pm,我在试着理解这个问题 Perl模块 我想从$var中获取值和机器,但即使使用正则表达式,我也无法使代码正常工作 我想从$var获取机器和命令提示符中的值(如机器1-7),但我不知道为什么它会在终端中打印$var,因为我没有调用$var变量 $Expect::Exp_Internal =0; my $admin_user = "root"; my $timeout = 40; my $prompt = '~]#'; my @devices =qw( machine1 machine2 mach

我在试着理解这个问题 Perl模块

我想从
$var
中获取值和机器,但即使使用正则表达式,我也无法使代码正常工作

我想从
$var
获取机器和命令提示符中的值(如机器1-7),但我不知道为什么它会在终端中打印
$var
,因为我没有调用
$var
变量

$Expect::Exp_Internal =0;
my $admin_user = "root";
my $timeout = 40;
my $prompt = '~]#';


my @devices =qw(
machine1
machine2
machine3);


foreach my $device (@devices){
my $exp = Expect->spawn("ssh", "-o", "UserKnownHostsFile /dev/null", "root\@$device");

$exp->log_user(0);


my $seen_user = 0;


$exp->expect(
    $timeout,
    [
        qr/connecting \(yes\/no\)\? / => sub {
            my $self = shift;
            $self->send("yes\r");
            exp_continue;
        }
    ],
    [
        qr/User: ?/ => sub {
            my $self = shift;
            if ( $seen_user == 1 ) {
                $var .= "Bad password on $device \n<br>";
                $exp->soft_close();
            }
            #  $self->send("$admin_user\n<br>");
            $seen_user = 1;
            exp_continue;
        }
    ],
    [
        qr/$prompt/ => sub {
            my $self = shift;
            #    print 'first_prompt';
        }
    ],
    [
        'timeout' => sub {
            $var .= "timed out during login on $device\n<br>";
        }
    ]
);

$exp->log_user(1);

# This following line is printed, without being called:

my $var = $exp->send("ps -aef | grep -i app | wc -l\n");

#$var =~ s/\D+//g;
#print 'numbers'.$var;

print $var;
undef $var;

my $logout_sent = 0;

$exp->expect(
    $timeout,
    [
        qr/$prompt/ => sub {
            my $self = shift;
            $exp->log_user(0);
            # $self->send("ps -aef | grep -i sql | wc -l\r");
            $self->send("logout\r");
            $logout_sent = 1;
            exp_continue;
        }
    ],

    }],

    [
        qr/\(y\/N\)/ => sub {
            my $self = shift;
            $self->send("y");
            print "ok\n<br>";
            #    exit 0;
        }
    ],
    [
        'timeout' => sub {
            print "timed out waiting for prompt\n<br>";
            # exit 1;
        }
    ],
    [
        'eof' => sub {
            if ($logout_sent) {
                $var .= "succesfully logged out from the $device\n<br>";
                #exit 0;
            }
            else {
                $var .="unexpected eof waiting for prompt on $device\n<br>";
            }
        }
    ]
);

}
$Expect::Exp\u Internal=0;
我的$admin\u user=“root”;
我的$timeout=40;
我的$prompt='~]#';
my@devices=qw(
机器1
机器2
机器3);
foreach my$设备(@devices){
my$exp=Expect->spawn(“ssh”、“-o”、“UserKnownHostsFile/dev/null”、“root\@$device”);
$exp->log\u用户(0);
我的$seen\U用户=0;
$exp->expect(
$timeout,
[
qr/连接\(是\/否\)\?/=>sub{
我的$self=shift;
$self->send(“yes\r”);
实验继续;
}
],
[
qr/用户:?/=>子系统{
我的$self=shift;
如果($seen\u user==1){
$var.=“$device上的密码错误\n
”; $exp->soft_close(); } #$self->send($admin\u user\n
); $seen_user=1; 实验继续; } ], [ qr/$prompt/=>sub{ 我的$self=shift; #打印“第一个提示”; } ], [ “超时”=>sub{ $var.=“登录$device时超时\n
”; } ] ); $exp->log_用户(1); #打印以下行,不调用: 我的$var=$exp->send(“ps-aef | grep-i app | wc-l\n”); #$var=~s/\D+//g; #打印“数字”。$var; 打印$var; 未定义$var; 我的$logout\u sent=0; $exp->expect( $timeout, [ qr/$prompt/=>sub{ 我的$self=shift; $exp->log\u用户(0); #$self->send(“ps-aef | grep-isql | wc-l\r”); $self->send(“注销\r”); $logout_sent=1; 实验继续; } ], }], [ qr/\(y\/N\)/=>sub{ 我的$self=shift; $self->send(“y”); 打印“确定”\n
; #出口0; } ], [ “超时”=>sub{ 打印“等待提示超时\n
”; #出口1; } ], [ “eof”=>sub{ 如果($logout\u已发送){ $var.=“成功从$device注销\n
”; #出口0; } 否则{ $var.=“意外的eof等待$device上的提示\n
”; } } ] ); }
输出


ps-aef | grep-i app | wc-l 7. [root@machine1~]#已成功从计算机注销1
ps-aef | grep-i应用程序| wc-l 9 [root@machine2~]#已成功从计算机注销2
ps-aef | grep-i应用程序| wc-l 7. [root@machine3~]#已成功从计算机注销3

您可以通过以下方式获得机器的值:

# $exp->clear_accum(); # clear the accumulator if you need to
$exp->expect( $timeout, '-re', 'root@machine\d+');
my ($machine_number) = $exp->match() =~ /root@machine(\d+)/;
$exp->clear_accum(); # clear the accumulator if you need to
$exp->send("ps -aef | grep -i app | wc -l\n");
$exp->expect( $timeout, '-re', '^\d+');
my ($num_processes) = $exp->match() =~ /(\d+)/;
然后,您可以得到如下所示的进程数:

# $exp->clear_accum(); # clear the accumulator if you need to
$exp->expect( $timeout, '-re', 'root@machine\d+');
my ($machine_number) = $exp->match() =~ /root@machine(\d+)/;
$exp->clear_accum(); # clear the accumulator if you need to
$exp->send("ps -aef | grep -i app | wc -l\n");
$exp->expect( $timeout, '-re', '^\d+');
my ($num_processes) = $exp->match() =~ /(\d+)/;

我整理了您的Perl代码,以便能够理解它。你应该仔细地缩进你写的任何东西,至少这样你可以自己阅读,尤其是当你在寻求帮助的时候。您显示的代码甚至都没有编译,因此它肯定不会产生您所说的输出。发布与您遇到问题的版本行为不同的代码毫无意义:我们不可能帮助您修复一个虚构的程序。你应该学习。很难说代码的实际输出是什么。您已经在
元素中包含了一些HTML输出,堆栈溢出已经格式化了结果文本。发布任何类型的文本数据都有特定的规定:只需将要显示的数据添加到帖子中,并将其缩进四个空格即可。您可以选择数据并使用Ctrl-K来实现这一点,也可以单击{}图标来执行相同的操作。所有这些都在每个编辑窗口上方的工具栏上进行了解释。您所说的“这一行是打印的,没有调用:”,是什么意思。你是说
my$var=$exp->send(“ps-aef | grep-i app | wc-l\n”)
出现在控制台上,但是
ps
grep
wc
没有运行吗?这似乎不太可能。嗨,Borodin,谢谢你的帮助,我添加了变量定义和for循环,使代码与我编译的代码完全一致。我对输出做了斜体显示,以强调执行脚本后控制台中的内容。我不明白为什么控制台中会显示这个变量,我的感觉是Expect模块中的send函数没有很好的文档化,可能我遗漏了一些bits@AndreiVieru在生成
ssh
之前,您可能必须使用
$exp->slave->stty('-echo')
关闭终端echo。这需要使用
IO::Stty
模块。很抱歉,我否决了您的答案,但问题本身仍然存在疑问,如果您想为半形式的问题提供解决方案,则需要指定您正在解决的解释。您还发布了无法解释的代码,从而降低了其他人从该页面获益的机会。