【发布时间】:2014-07-14 06:34:31
【问题描述】:
Linux 的内核级控制台/非 X 终端仿真器包含一个非常酷的特性(如果在其中编译):每个/dev/ttyN 设备对应于/dev/vcsaN 和/dev/vcsN 设备表示该 tty 的内存中(显示)状态,分别有和没有属性(颜色、闪烁等)。这使您可以非常轻松地cat /dev/vcs7 并在启动cat 的任何地方看到/dev/tty7 的转储。
前几天,我使用这个令人难以置信的实用功能通过 SSH 登录到系统并远程观看我忘记放入 screen(或类似)会话的 dd 进程 - 它正在运行文本控制台,所以我花了一些时间来微调我想要抓取的字符范围,目前我正在通过 SSH 观看dd 的传输状态(顺便说一下,每秒一次)。
重申和澄清,/dev/vcs{,a}* 是字符设备,用于检索内核控制台 VT100 仿真器的当前内存表示,表示为单个“行”文本(每个“行”)。
为了消除混淆,我想指出我不能tail -f 这个设备:它不是像 TTY 本身那样的字符流。 (但我从来不需要这种行为,因为它值得。)
多年来,我一直在寻找一种方法来转储 X 终端仿真器的字符单元内存状态 - 或者实际上是任何需要使用 ttys 的任意进程,以与我可以使用类似的方式Linux 控制台。而且......我很惊讶这个问题没有实际的解决方案 - 因为它可以说已经存在了大约 30 年 - X 是在 1984 年推出的 - 或者,学究起来,至少 19 年 - /dev/vcs{,a}* 在内核 1.1.94 中引入;该版本中的最新文件日期为 1995 年 2 月 22 日。(最早的文件是 1993 年 12 月 1 日:P)
我想说的是,我确实理解并意识到 tty 本身并不是一个“屏幕缓冲区”,而是一个字符流,并且我在上面基本上利用的非标准功能是 Linux VT102 特有的一种古怪功能模拟器。然而,这个功能已经足够酷了(为什么它会在主线树中?:D),在我看来,有 应该与 /dev/pts* 一起工作的东西与之对应。
今天下午,我需要对交互式 ncurses 应用程序的输出进行屏幕抓取,以便从终端中显示的信息中提取元数据。 (没有其他实用的方法可以实现我的目标。)Linux 的内核 VT100 驱动程序可以轻松完成这样的任务非常,我做了错误地认为,鉴于此,在 X11 下做同样的事情不可能真的那么难。
到上午 9 点,我决定尝试性地请求远程屏幕转储的最简单方法是在 dtach 中运行它(认为“screen -x”没有任何其他选项)并破解 dtach请求屏幕更新并退出的代码。
大约上午 11 点到下午 12 点,我请求更新屏幕并将其转储到 stdout。
下午 3:30 左右,我接受了使用 dtach 是不可能的:
- 首先,它依赖于应用程序本身根据请求发送屏幕重绘,通过设计来保持代码简单。这很好,但是,幸运的是,我使用的应用程序不支持全屏重绘 - 它只会在屏幕尺寸变化时重绘(并且只有在屏幕尺寸真正不同的情况下!)。李>
- 在
screen会话中运行程序(因为screen是一个真正的终端模拟器,并且有一个内部2D 字符单元缓冲区),然后在dtach中运行screen -x,也神秘地无法生成字符单元更新。
我之前检查过screen,发现代码足够疯狂,足以消除我可能不得不破解它的任何倾向;我只能说,这种精神错乱可能是screen 还没有我在这里介绍的功能的原因之一(可以说这很容易实现)。
与此类似的其他问题经常使用 typescript 或script 得到答案;我只是想澄清script 将tty 本身的流 保存到一个文件中,我需要通过一个VT100 模拟器来获取该tty 当前状态的屏幕图像问题。换句话说,script 将是我的问题的一个非常疯狂的解决方案。
【问题讨论】:
标签: linux terminal console screen-scraping gnu-screen