我如何"转储"一个X终端的内容在Linux控制台中以编程方式la / dev / vcs {,a}?

时间:2014-07-14 06:34:32

标签: linux terminal console screen-scraping gnu-screen

Linux的内核级控制台/非X终端仿真器包含一个非常酷的功能 (如果已编译) :每个/dev/ttyN设备对应{{ 1}}和/dev/vcsaN设备,分别表示该tty的内存(显示)状态,包含和不包含属性(颜色,闪烁等)。这样,您就可以非常轻松/dev/vcsN,并在cat /dev/vcs7启动/dev/tty7的任何地方看到转储cat。我前几天使用这种非常实用的功能通过SSH登录系统并远程观察dd我忘记放入screen(或类似)会话的过程 - 它我正在运行一个文本控制台,所以我花了一些时间来微调我想要抓取的角色范围,现在我正在通过SSH观察dd的传输状态(偶然每秒一次)。

重申并澄清,/dev/vcs{,a}*是检索内核控制台VT100仿真器的当前内存中表示的字符设备,表示为文本的单个“行”(结尾处没有“换行符”)屏幕的每个“线”)。
为了消除混淆,我想注意我不能tail -f这个设备:它不是像TTY本身那样的字符流。 (但我从来不需要这种行为,因为它的价值。)

多年来,我一直倾听我的耳朵,以获得一种方法来转储X终端仿真器的字符单元内存状态 - 或者实际上任何需要使用ttys的任意进程,以类似于我可以使用的方式Linux控制台。并且...我很惊讶没有实际解决这个问题的方法 - 因为它可以存在大约30年--X是在1984年引入的 - 或者,讽刺的是,至少 19年 - 内核1.1.94中引入了/dev/vcs{,a}*;该版本的最新文件日期为1995年2月22日。 (最早的是1993年12月1日:P)

我想说我确实理解并意识到tty本身不是一个“屏幕缓冲区”,而是一个字符流,而我上面基本上利用的非标准功能是一个特殊于Linux VT102的奇特功能模拟器。但是,这个功能足够酷(为什么它还会出现在主线树中? :D ),在我看来,<对于与/dev/pts*一起使用的内容,strong>应该成为它的对应部分。

今天下午,我需要屏幕截取交互式ncurses应用程序的输出,这样我就可以从终端中显示的信息中提取元数据。 (没有其他实用的方法来实现我的目标。)Linux的内核VT100驱动程序将允许轻松完成 非常 这样的任务,我做了认为它的错误,鉴于此,它不能真正在X11下难以做到这一点。

到了早上9点,我决定以实验方式请求转储远程屏幕的最简单方法是在dtach中运行它(在没有任何其他选项的情况下认为“screen -x”)并且黑客攻击dtach代码请求屏幕更新并退出。

大约上午11点到12点,我正在请求屏幕更新并将其转储到stdout

下午3:30左右,我接受使用dtach是不可能的:

  • 首先,它依赖于应用程序本身根据请求发送屏幕重绘,以保持代码简单。这很好,但是,幸运的是,我使用的应用程序不支持全屏重绘 - 它只会重新绘制屏幕尺寸的变化(并且只有在屏幕尺寸真的不同的情况下!)。
  • screen会话中运行程序(因为screen是真正的终端仿真器并且具有内部2D字符单元缓冲区),然后在screen -x内运行dtach ,也神秘地未能产生角色细胞更新。

我之前已经检查了screen,并发现代码足够疯狂,以消除我可能不得不破解它的任何倾向;我可以说的是,所说的精神错乱可能是screen还没有我在这里提出的能力的原因之一(这可能很容易实现)。

与此类似的其他问题经常得到使用打字稿或script的答案;我只想澄清script本身的流保存到文件中,我需要通过VT100模拟器来获取当前状态的屏幕图像。有问题的。换句话说,script对我的问题来说是一个非常疯狂的解决方案。

1 个答案:

答案 0 :(得分:0)

我并不认为这是被接受的,因为它没有解决实际的核心问题(这已经很多年了),但我能够实现我打算做的具体目标。

我的具体要求是我想屏幕截取ncdu交互式磁盘使用浏览器的输出,所以我只需按下另一个终端的Enter(或执行一些类似的,简单的序列)来添加目录当前在ncdu中突出显示/选择了我想要使用的文件的文件列表。
我的目标是不必分散我自己的无限复制+粘贴和/或重新输入目录名称(可能没有一些不准确的启动),所以我可以专注于我想要选择的目录。

screen有一个刷新功能,按下(默认情况下) CTRL + A,CTRL + L 即可访问。我将dtach的副本扩展为除了将远程屏幕转储到stdout之外还能够发送击键,并将dtach包装在一个脚本中,该脚本将刷新序列(\001\014)发送到{{ 1}}在screen -x内运行。这完美地工作,检索完整的屏幕更新,没有任何闪烁。

但是,我会警告任何有兴趣尝试这种技术的人,你需要完善躲避VT100逃脱序列的艺术。我使用正则表达式,所以我没有编写成千上万行代码;这是脚本的特定部分,它提取了我需要的两条信息:

dtach

由于屏幕截图很酷并且可以帮助人们想象事物,所以在这里看看它在运行时的工作原理:

Screenshot of ncdu-scrape

在ncdu窗口底部反转显示的文件正在从ncdu窗口本身进行屏幕抓取;列表中的四个文件都在那里,因为我使用sh -c "(sleep 0.1; dtach -k qq $'\001\014') &"; path="$(dtach -d qq -t 130000 | sed -n $'/^\033\[7m.*\/\.\./q;/---.*$/{s/.*--- //;s/ -\+.*//;h};/^\033\[7m/{s/.\033.*//g;s/\r.*//g;s/ *$//g;s/^\033\[7m *[^ ]\+ \[[# ]*\] *\(\/*\)\(.*\)$/\/\\2\\1/;p;g;p;q}' | sed 'N;s/\(.*\)\n\(.*\)/\2\1/')"中的箭头键选中它们,将鼠标移动到ncdu-scrape窗口(我使用focus-follow-mouse),然后按Enter键。这将文件添加到列表中(一个简单的文本文件本身)。

话虽如此,我想澄清一下,上面的正则表达式不是运行的代码示例;更确切地说,这是一个警告:对于任何超出难以置信的琐碎 !! )内容提取的内容,例如此处提供的内容,您基本上会进入同一领域。希望从基于VT100的系统转换为更现代化的大型企业/利益集团,他们需要花费数千美元来调试大型翻译框架,这些翻译框架能够在特别大的范围内执行上述转换。

Saner解决方案赞赏。