Печать ожидаемого вывода без вызова переменной

Я пытаюсь понять модуль Perl Expect.

Я хочу взять значение и машину из $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>";
            }
        }
    ]
);

}

Выход

<br>ps -aef | grep -i app | wc -l
7
[root@machine1 ~]# succesfully logged out from the machine1
<br>ps -aef | grep -i app | wc -l
9
[root@machine2 ~]# succesfully logged out from the machine2
<br>ps -aef | grep -i app | wc -l
7
[root@machine3 ~]# succesfully logged out from the machine3


person Andrei Vieru    schedule 03.09.2018    source источник
comment
Я привел в порядок ваш код Perl, чтобы понять его. Вы должны тщательно делать отступы во всем, что вы пишете, по крайней мере, чтобы вы могли прочитать это сами, но особенно, если вы просите помощи с этим. Код, который вы показываете, даже не компилируется, поэтому он, конечно, не дает того вывода, о котором вы говорите. Нет никакого смысла публиковать код, который ведет себя иначе, чем версия, с которой у вас возникли проблемы: мы не можем помочь вам исправить воображаемую программу. Вам следует изучить Как создать минимальный, полный и проверяемый пример.   -  person Borodin    schedule 03.09.2018
comment
Очень сложно сказать, каков реальный результат вашего кода. Вы заключили вывод HTML в элемент <i>, и Stack Overflow отформатировал получившийся текст. Существует специальное положение для публикации текстовых данных любого типа: вы просто добавляете данные, которые хотите показать, в свой пост и делаете отступ на четыре пробела. Вы можете выбрать данные и использовать для этого Ctrl-K или щелкнуть значок { }, чтобы сделать то же самое. Все это объясняется в справке по редактированию, которая находится на панели инструментов над каждым окном редактирования.   -  person Borodin    schedule 03.09.2018
comment
Что вы подразумеваете под Эта следующая строка печатается без вызова:. Вы хотите сказать, что my $var = $exp->send("ps -aef | grep -i app | wc -l\n") отображается в консоли, но ps, grep и wc не запускаются? Это кажется очень маловероятным.   -  person Borodin    schedule 03.09.2018
comment
Привет, Бородин, спасибо за помощь, я добавил определение переменной и цикл for, чтобы код был точно таким, как я его компилирую. Я выделил вывод курсивом, чтобы подчеркнуть то, что у меня есть в консоли после выполнения скрипта. Я не понимаю, почему в консоли отображается эта переменная, и мне кажется, что функция отправки в модуле Expect не очень документирована, и, возможно, я пропустил некоторые биты.   -  person Andrei Vieru    schedule 04.09.2018
comment
@AndreiVieru Возможно, вам придется отключить эхо терминала с помощью $exp->slave->stty( '-echo' ), прежде чем вы создадите ssh. Для этого требуется модуль IO::Stty.   -  person Håkon Hægland    schedule 04.09.2018
comment
@AndreiVieru: Я выделил курсивом вывод, чтобы подчеркнуть, что у меня есть в консоли после выполнения скрипта Курсив не подходит ни для данных, ни для кода. Существует определенный стандарт разметки для обоих встроенных в Stack Overflow, и вы должны использовать его. Пожалуйста, изучите справку по уценке и внимательно применяйте ее. Я сделал все возможное, чтобы улучшить ваш вопрос, но только вы можете отредактировать его, чтобы точно представить вашу ситуацию.   -  person Borodin    schedule 05.09.2018


Ответы (1)


Вы можете получить стоимость машины следующим образом:

# $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+)/;
person Håkon Hægland    schedule 03.09.2018
comment
Мне жаль, что я проголосовал против вашего ответа, но сам вопрос все еще вызывает сомнения, и если вы хотите дать решение наполовину сформированного вопроса, вам нужно указать интерпретацию, которую вы решаете. Вы также разместили необъяснимый код, тем самым уменьшив даже шанс, что другие получат пользу от этой страницы. - person Borodin; 05.09.2018