![创建伪终端的程序是否模拟终端?](https://linux22.com/image/202076/%E5%88%9B%E5%BB%BA%E4%BC%AA%E7%BB%88%E7%AB%AF%E7%9A%84%E7%A8%8B%E5%BA%8F%E6%98%AF%E5%90%A6%E6%A8%A1%E6%8B%9F%E7%BB%88%E7%AB%AF%EF%BC%9F.png)
根据我的理解,创建 pty(主/从对)的应用程序可以分为两类:
- 终端仿真器(
xterm
、urxvt
、 ...),据说可以产生图形输出 - 其余的(
docker
、ssh
、tmux
、screen
...),据说会产生文本输出
这意味着,前者或多或少必须在图形显示上绘图。后者为前者生成文本输出(可选地带有转义序列)。你应该得到的是一系列终端模拟器(例如xterm
<-> ssh
<-> tmux
<-> docker
)。链的各个部分将转义序列从一种语言翻译成另一种语言。或者更准确地说,它们处理转义序列,并使用terminfo
数据库将它们翻译到下一个终端模拟器。
下图来自“TTY 揭秘”这里可能也是有序的:
那么,是什么造成了xterm
xterm
? 是xterm
处理转义序列,还是只是让内核完成工作? 换句话说,xterm
terminfo
数据库条目...它对应于内核,还是对应于xterm
? 好吧,这样说,答案似乎很明显。 虽然我仍然不知道内核是否会以某种方式影响terminfo
数据库条目。
那么其他程序呢?创建 pty 是否会为您提供一个不处理转义序列的空白终端,并且您负责添加此类处理?这意味着您处理的转义序列决定了TERM
另一端变量的值?我这里缺少什么吗?
这个问题的灵感来自于以下答案,作者声称该TERM
值并不重要。
答案1
图像是正确的。内核(至少在这个问题的上下文中)确实不是充当终端模拟器。它处理线路纪律,请参阅stty(1)
和termios(3)
手册以了解线路纪律的含义。它包括 CR-LF 转换、^C
(中断)处理、一些最小的行编辑功能(称为“熟”模式,它实现了退格键的处理,^W
朋友们,如果您执行的命令cat
没有自己的行编辑功能) ,并且仅在按 Enter 时发送整行)、控制流、串行端口属性(几乎已过时)等。但它不处理\e
转义字符。
现在,Linux 内核确实实现了一个终端仿真器,类似于映像中的“xterm”节点。它是虚拟控制台(通常是 Ctrl+Alt+F1 等),是vt
Linux 内核的组件而不是组件tty
。就这个问题而言,这是无关紧要的;而且我还发现你的问题并不是特定于 Linux 的,我在这方面不熟悉其他 Unix 变体。
是
xterm
处理转义序列,还是只是让内核完成工作?
这是xterm
。过于简单的故事:当 xterm 启动时,它会建立一个 tty 线路(主端和从机端),启动一个连接到该 tty 的命令(通常是一个 shell,图中的“用户进程”,如果TERM
设置正确的话)显示一个图形窗口,光标位于左上角。然后它进行双向通信。
对于按键,它会传输其序列,如图箭头所示。根据行规则,内核可能会自行处理它(例如,如果您正在运行cat
并按字母“x”,它尚未发送到cat
,它是处理基本行编辑的内核),在这种情况下,内核将告诉终端如何更新显示(可能通过打印“x”);或者它可以将按键转发到相关的用户进程。
在另一个方向上,用户进程可能想要也可能不想更新其显示(并且它可能想要执行此操作,而不管接收到的按键),数据以相反的方向遍历该路径。
假设一个应用程序输出x\e[31my\n
.线路规则转换\n
为\r\n
(否则你最终会得到“楼梯效应”),但它不关心字符\e
,因此终端模拟器接收x\e[31my\r\n
.
xterm
收到此消息并说:我需要x
在光标处打印 an,然后\e[31m
意味着我需要切换到红色,然后打印 a y
(红色),然后将光标前后移动一行。它会这样做并相应地更新其显示。
换句话说,
xterm
terminfo
数据库条目...它对应于内核,还是对应于xterm
?
术语信息描述各种终端仿真器对用户应用程序的行为(因为所有终端仿真器处理转义序列的方式都略有不同)。内核对此一无所知。
虽然内核和 terminfo 所说的内容有轻微的重叠,例如 terminfo 可能包含退格字符的条目(无论是^H
或^?
),但此行为是在行规则中实现的,而不是在终端仿真器中实现的。终端仿真器应该相应地配置线路规则,从这个意义上说,它描述了终端仿真器的行为是有效的,即使它不是终端仿真器本身,但它将此任务委托给内核的线路规则。无论如何,我离题了,这是例外,而不是规则。规则是 terminfo 描述终端仿真器自身的行为。
创建伪终端的程序是否模拟终端?
不,不一定。我会对创建终端线的应用程序进行分类,如下所示:
- 终端仿真器 (
xterm
,urxvt
,screen
,tmux
, ...) - 不是终端模拟器(
ssh
(交互或-t
给出时)、、、script
...luit
)
我不熟悉,docker
但我怀疑它属于第二组。
第二组包含的应用程序本质上需要创建 tty 线路,但仅用于转发或记录或简单操作与转义序列无关的数据。这些应用程序不知道\e
意味着什么,不知道\e[31m
红色意味着什么,甚至不知道“红色”意味着什么,不知道终端的画布在给定时刻应该是什么样子。
第一组是必须关心此类转义序列的应用程序。一开始screen
可能tmux
会令人惊讶,但这些应用程序绝对没有机会通过盲目转发数据来实现其行为 - 当您重新附加或在选项卡之间切换时,它们将无法恢复画布,更不用说处理窗格布局了一次多个终端。这些工具必须解析并完全理解每个转义序列,并在其内存中跟踪画布到底需要是什么样子。
我更喜欢将screen
和tmux
视为终端模拟器,与 和 朋友的主要区别xterm
在于它们的后端,即向用户呈现内容的画布,是另一个终端模拟器的字符网格,而不是窗口上的像素。图形用户界面。 (另一个主要区别是分离和重新连接的能力,这与这里无关。)
我希望这一切都有道理。