如何在 Perl 中从 telnet 屏幕抓取输出?

发布于 2024-08-21 08:40:08 字数 694 浏览 11 评论 0原文

我可以在 Perl 中毫无问题地设置 telnet 连接,并且刚刚发现了 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 在行\列的基础上进行搜索。有谁知道我可以将两者连接在一起的方法吗?在我看来,curses只能在STDOUT上操作

I can setup a telnet connection in Perl no problems, and have just discovered Curses, and am wondering if I can use the two together to scrape the output from the telnet session.

I can view on a row, column basis the contents of STDOUT using the simple script below:

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

And using the below I can open a telnet connection and send \ receive commands with no problem:

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");

... But what I would really like to do is get the telnet response (which will include terminal control characters) and then search on a row \ column basis using curses. Does anyone know of a way I can connect the two together? It seems to me that curses can only operate on STDOUT

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

肥爪爪 2024-08-28 08:40:08

诅咒则相反。它是一个 C 库,用于优化从程序写入终端的屏幕更新,最初设计用于在慢速串行连接上使用。它无法从控制字符序列中抓取布局。

更好的选择是拥有一个能够执行此类屏幕抓取功能的 API 的终端模拟器。我不确定是否有开源终端模拟器可以做到这一点,但肯定有商业终端模拟器可以做到这一点。

Curses does the opposite. It is a C library for optimising screen updates from a program writing to a terminal, originally designed to be used over a slow serial connection. It has no ability to scrape a layout from a sequence of control characters.

A better bet would be a terminal emulator that has an API with the ability to do this type of screen scraping. Off the top of my head I'm not sure if any Open-source terminal emulators do this, but there are certainly commercial ones available that can.

星星的軌跡 2024-08-28 08:40:08

如果您纯粹与纯文本命令和响应进行交互,则可以使用 Expect< /a> 编写脚本,否则,您可以使用 Term ::VT102,它允许您使用 VT102 转义序列进行屏幕控制(例如,使用curses库的应用程序)。

If you are interacting purely with plain-text commands and responses, you can use Expect to script that, otherwise, you can use Term::VT102, which lets you screen scrape (read specific parts of the screen, send text, handle events on scrolling, cursor movement, screen content changes, and others) applications using VT102 escape sequences for screen control (e.g., an application using the curses library).

穿透光 2024-08-28 08:40:08

您可能想要类似 Expect 的内容

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

You probably want something like Expect

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;
                }
        ]
);
梦里寻她 2024-08-28 08:40:08

您正在寻找 Term::VT102,它模拟 VT102 终端(将终端控制字符回到虚拟屏幕状态)。有一个示例显示如何在 Net::Telnet 中使用它="http://cpansearch.perl.org/src/AJWOOD/Term-VT102-0.91/VT102/examples/telnet-usage.pl" rel="nofollow noreferrer">VT102/examples/telnet-usage.pl (由于某种原因,示例目录位于 VT102 目录内)。

自从我使用这个以来已经有大约 7 年了(我正在自动化的系统切换到基于网络的界面),但它曾经可以工作。

You're looking for Term::VT102, which emulates a VT102 terminal (converting the terminal control characters back into a virtual screen state). There's an example showing how to use it with Net::Telnet in VT102/examples/telnet-usage.pl (the examples directory is inside the VT102 directory for some reason).

It's been about 7 years since I used this (the system I was automating switched to a web-based interface), but it used to work.

满意归宿 2024-08-28 08:40:08

或者您可以使用 script 命令来实现此目的。

来自 Solaris 手册页:

描述

script实用程序记录所有打印的内容
在你的屏幕上。记录写入文件名。如果没有文件名
给定后,记录保存在文件 typescript...

脚本命令分叉并创建一个
子shell,根据值
$SHELL,并记录此中的文本
会议。脚本结束时
分叉 shell 退出或当
键入 Control-d。

Or you could use the script command for this.

From the Solaris man-page:

DESCRIPTION

The script utility makes a record of everything printed
on your screen. The record is written to filename. If no file name
is given, the record is saved in the file typescript...

The script command forks and creates a
sub-shell, according to the value of
$SHELL, and records the text from this
session. The script ends when the
forked shell exits or when
Control-d is typed.

临风闻羌笛 2024-08-28 08:40:08

我也会投票支持 Expect 答案。我必须从 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];
}

I would vote also for the Expect answer. I had to do something similar from a gui'ish application. The trick (albeit tedious) to get around the control characters was to strip all the misc characters from the returned strings. It kind of depends on how messy the screen scrape ends up being.

Here is my function from that script as an example:

# 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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文