Как я могу проверить вывод из telnet в Perl? - PullRequest
8 голосов
/ 10 февраля 2010

Я могу установить соединение telnet в Perl без проблем, и только что обнаружил Curses, и мне интересно, могу ли я использовать два вместе для очистки вывода из сеанса telnet.

Я могу просматривать в строке, столбце содержимое STDOUT, используя простой скрипт ниже:

use Curses;
my $win = new Curses;
$win->addstr(10, 10, 'foo');
$win->refresh;
my $thischar=$win->inch(10,10);
print "Char $thischar\n";

И используя нижеприведенное, я могу без проблем открыть соединение telnet и отправить \ получить команды:

use net::telnet;
my $telnet = new Net::Telnet (Timeout => 9999,);
$telnet->open($ipaddress) or die "telnet open failed\n";
$telnet->login($user,$pass);
my $output = $telnet->cmd("command string");

... Но то, что я действительно хотел бы сделать, это получить ответ telnet (который будет включать управляющие символы терминала), а затем выполнить поиск по строке / столбцу с использованием curses. Кто-нибудь знает, как я могу соединить два вместе? Мне кажется, что проклятия могут действовать только на STDOUT

Ответы [ 6 ]

5 голосов
/ 10 февраля 2010

Curses делает наоборот.Это библиотека C для оптимизации обновления экрана от записи программы к терминалу, изначально разработанная для использования по медленному последовательному соединению.У него нет возможности очищать макет от последовательности управляющих символов.

Лучше было бы сделать эмулятор терминала, у которого есть API с возможностью делать этот вид скрепления экрана.Я не уверен, что какие-либо эмуляторы терминалов с открытым исходным кодом делают это, но есть коммерческие, которые могут это сделать.

4 голосов
/ 10 февраля 2010

Вы, вероятно, хотите что-то вроде Ожидайте

use strict;
use warnings;

use Expect;

my $exp = Expect->spawn("telnet google.com 80");

$exp->expect(15, #timeout
        [
                qr/^Escape character.*$/,
                sub {
                        $exp->send("GET / HTTP/1.0\n\n");
                        exp_continue;
                }
        ]
);
3 голосов
/ 10 февраля 2010

Если вы взаимодействуете исключительно с простыми текстовыми командами и ответами, вы можете использовать Ожидать для сценария, в противном случае вы можете использовать Term :: VT102 , что позволяет вам отображать очищать (читать определенные части экрана, отправлять текст, обрабатывать события при прокрутке, перемещении курсора, изменениях содержимого экрана и т. д.) приложения, использующие escape-последовательности VT102 для управления экраном (например, приложение, использующее библиотеку curses).

3 голосов
/ 10 февраля 2010

Вы ищете Term :: VT102 , который эмулирует терминал VT102 (преобразование управляющих символов терминала обратно в состояние виртуального экрана). Есть пример, показывающий, как его использовать с Net :: Telnet в VT102 / examples / telnet-usage.pl (каталог с примерами находится внутри каталога VT102 по некоторым причинам).

Прошло около 7 лет с тех пор, как я использовал это (система, которую я автоматизировал, переключился на веб-интерфейс), но она работала.

1 голос
/ 10 февраля 2010

Или для этого вы можете использовать команду script .

С man-страницы Solaris:

ОПИСАНИЕ

Утилита script делает запись всего напечатанного на вашем экране. Запись записывается в имя файла . Если нет имени файла дается, запись сохраняется в файле машинопись ...

Команда сценария разветвляется и создает под-оболочка, в соответствии со значением $ SHELL и записывает текст с этого сессия. Сценарий заканчивается, когда разветвленная оболочка выходит или когда Control-d набрано.

0 голосов
/ 11 февраля 2010

Я бы тоже проголосовал за ожидаемый ответ. Мне пришлось сделать что-то подобное из приложения gui'ish. Хитрость (хотя и утомительная) для обхода управляющих символов состояла в том, чтобы убрать все разные символы из возвращаемых строк. Это зависит от того, насколько грязным будет скребок экрана.

Вот моя функция из этого скрипта в качестве примера:

# Trim out the curses crap
sub trim {
    my @out = @_;
    for (@out) {
        s/\x1b7//g;
        s/\x1b8//g;
        s/\x1b//g;   # remove escapes
        s/\W\w\W//g;
        s/\[\d\d\;\d\dH//g;  # 
        s/\[\?25h//g;
        s/\[\?25l//g;
        s/\[\dm//g;
        s/qq//g;
        s/Recall//g;
        s/\357//g;
        s/[^0-9:a-zA-Z-\s,\"]/ /g;
        s/\s+/ /g;    # Extra spaces

    }
    return wantarray ? @out : $out[0];
}
...