Как я могу экранировать вывод из telnet в Perl?

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

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

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

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

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

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

6 ответов


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

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


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

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


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

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;
                }
        ]
);

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


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

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

описание

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

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


Я бы также проголосовал за ожидаемый ответ. Я должен был сделать что-то подобное из приложения 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/7//g;
        s/[^0-9:a-zA-Z-\s,\"]/ /g;
        s/\s+/ /g;    # Extra spaces

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