![回显的转义序列在 Linux tty 中不被解释](https://linux22.com/image/153314/%E5%9B%9E%E6%98%BE%E7%9A%84%E8%BD%AC%E4%B9%89%E5%BA%8F%E5%88%97%E5%9C%A8%20Linux%20tty%20%E4%B8%AD%E4%B8%8D%E8%A2%AB%E8%A7%A3%E9%87%8A.png)
先决条件
Linux 虚拟终端 (tty) 是对VT102-虚拟终端子系统源码。
真实的VT100(几乎与VT102)有以下行为(我想):
- 在里面线模式下,所有键入的字符首先传输到计算机,然后返回到终端。从主机返回之前,终端屏幕上不会显示任何内容。
- 转义序列也不例外 - 它们仅在从主机返回后才会被解析和执行。也就是说,如果我想将字体颜色更改为红色,我应该输入
ESC[0;31m
,该序列将发送到计算机,并回显,VT102接收这个,解析并应用。没有其他方法可以更改终端字体颜色(在线模式)。我不确定是否VT102虽然字体颜色不同,但这只是一个例子。
图片来自手册:
手册摘录:
线路/本地
线路/本地功能允许操作员轻松地将终端置于在线或本地(离线)状态。当终端在线时(ON-LINE 指示灯亮起),键盘上输入的所有字符都会直接发送到计算机,并且来自计算机的消息会显示在屏幕上。在LOCAL状态下(LOCAL指示灯亮),终端与计算机电气断开;消息未发送到计算机或从计算机接收;键盘上输入的字符会直接回显在屏幕上。
资料来源:VT100系列视频终端技术手册,第三版,1982年7月。
问题
为什么 Linux 的tty
行为方式不同?
我将其bash
置于睡眠模式,因此它不会干扰,然后键入Esc[0;31m
并获取纯文本,颜色没有改变 - 因此,转义序列没有效果。
几年前我也被问过类似的问题 -为什么我无法从键盘发送转义序列,但可以从另一个 tty 发送转义序列?,但现在我了解了VT102Linux 子系统并希望了解它为什么以这种方式工作 - 在这方面与真实的硬件终端不同。
答案1
首先,这个问题是在复古计算,但社区发现它更适合这个网站。但我在评论部分得到了答案,所以复制到这里:
Linux 虚拟控制台以联机模式模拟连接到 Linux(串行)tty 设备的(某种)VT102 终端。 Linux tty 驱动程序通常不会回显转义控制字符,而是回显^[。如果您不希望 tty 驱动程序执行此操作,请使用斯蒂-克特莱乔。此外,真正的 VT102 终端不支持颜色,它无论如何都可以与 Linux 虚拟控制台一起使用,因为它并不真正兼容 VT102。
我已经尝试过,stty -ctlecho
它几乎按预期工作 - 只有一个子问题 - 是真正的VT102在人按下并开始输入转义序列后也没有显示字符ESC,所以人是以盲方式输入的?
答案2
很长的问题,简化为
为什么 Linux tty 的行为方式不同?
其实这不是终端,但是应用程序(例如您的壳) 控制回显字符的内容和方式。您可以使用stty
应用程序暂时更改终端模式(某些 shell 会将其更改回来),例如,
stty -cooked
(使其“原始”,告诉终端驱动程序不要干扰)。
答案3
...以盲方式输入
我想我们已经很接近了。你做了一个非常好的文档。只是缺少演示!在你的旧Q中从键盘发送转义序列你只展示了不起作用的东西!还有两个标题???你能不能说清楚一点吗?还有像我这样的屏幕截图(在我对上面链接的问题的回答中)
没有人应该进入其中之一长的序列盲目地。在一个设置良好的 VTxxx 上,您将拥有特殊的键和特殊的绑定,也许是 shell 函数,其中存储了 CS。在这样的系统上,一切都是协调的。 Linux 和 xterm 正在模仿它,因为它是唯一接近标准的东西。
但是,是的,Escape 键确实意味着:下一个键不是输入,而是命令。因此,必须有人开始保留字节并检查预定义的序列。
但如果序列变得不可能,外壳就会退出退出模式并再次开始回显。按 Escape、[,然后按 1,1,1...,括号和两个“1”就会丢失。
尝试在 Escape 之后输入[32m
...“m”再次出现,这意味着 shell 放弃了该序列。我应该说,无用的 ^[[32 丢失了,丢失在某个地方。
取消 bash/readline,让 tty 停止工作:您将只剩下一个孩子的玩具,您可以在屏幕上到处放置彩色字母(粗体、下划线、闪烁、不可见)。
我不明白你的问题。“回响转义序列”对我来说是一个没有到达目标并且真正得到反映的序列。就像当我尝试在读取提示符下使用向左箭头时(输入 abc 后):
$ read
abc^[[D
在正常提示符下,当我输入“abc”,然后输入 Escape,然后盲目地输入“[D”时,光标向左移动。箭头键只是一种更简单的生成方法。
要通过序列,请使用echo -e '\e...'
或echo '^[...'
(使用 ctrl-V)。这样 shell 就会发送转义字符并且不会解释(烹饪?)它。
而且你stty -echoctl
甚至sleep 1000
发现了一种直接把CS扔到tty脸上的方法。抱歉: tty 的司机的脸。
[这里我需要一个更好的更改颜色,而-bash-is-sleeping-and-tty-offguard jpeg...]