为什么我无法从键盘发送转义序列,但可以从另一个 tty 发送转义序列?

为什么我无法从键盘发送转义序列,但可以从另一个 tty 发送转义序列?

我试图通过执行不同的技巧来了解终端的工作原理,例如从一个 tty 写入另一个 tty、更改设置tty1tty2。此外,我还尝试通过直接从键盘发送转义序列来更改颜色。也就是说,不是通过echo -e '\e[0;31m'命令,而是通过直接键盘输入。这不起作用。

我执行以下步骤:

  1. 打开tty1tty2
  2. tty2进入bash睡眠模式时,按sleep 10m。输入单词“一”。

在此输入图像描述

  1. tty1,做echo -n ^[[0;31m > /dev/tty2。第一个字符^[是这样输入的Ctrl+v Esc
  2. 返回tty2,输入单词“two”。是的 - 颜色已通过另一个 tty 的命令更改为红色。

在此输入图像描述

  1. 重复步骤 3,4,但使用绿色和单词“三”

在此输入图像描述

  1. 最后,我尝试不通过另一个发送转义序列tty,而是直接从键盘发送转义序列 - 通过^[[0;37m输入 tty2.我以同样的方式做所有事情 - Esc(不需要Ctrl+ ,因为 readline 正在休眠),然后,但是得到这个:v[0;37m

在此输入图像描述

问题: 为什么会这样?所有字符相同,终端状态相同,但在一种情况下终端获得转义序列,而在另一种情况下则没有。


编辑

这个问题在这里得到了回答:回显的转义序列在 Linux tty 中不被解释

答案1

当你运行时echo,你正在发送输出到航站楼。终端解释转义序列,例如更改发送给它的输出中的颜色的转义序列。这些转义序列旨在由应用程序发送,这就是为什么它们在终端中运行的应用程序的输出中被识别的原因。通常,在终端中运行的应用程序是由终端仿真器(您的 shell)启动的应用程序,以及依次启动的应用程序,但如果您运行,echo … >/dev/tty2那么echo实际上是“在终端中运行”(从某种意义上说,它的输出是到终端,这才是重要的)。

当您按下Esc [等时,您正在发送输入到航站楼。终端不会解释转义序列,例如更改其接收的输入中的颜色的转义序列。终端确实会解释输入中的转义序列,但目的完全不同:它们是对功能键按下进行编码的一种方式。

键盘输入和文本输出如何工作?有一定的相关背景。

答案2

即使在 xorg 中的 xterm 中,这也有效:

stty -echoctl
sleep <a bit>

然后,在“死”的终端上,可以直接按Escape然后

[32m

您按下的下一个键已经是绿色的!如果您使用 ctrl-C 终止睡眠,您的提示符将保持干净......

在此输入图像描述

这个问题是一个非常特殊的情况——一种在 readline/bash 处于昏迷状态时将转义序列从键盘偷偷转移到屏幕的方法。

使用正常的 echoctl/ctlecho,在sleepshell 回显按键(输入)之后,还会像^[在屏幕上一样直接回显转义键(输出)。 “控制序列引入器 (CSI)”的特殊含义丢失。

那么(已接受的)答案不是错误的吗?


在这里,我按下 ctrl-C,并将光标放在“line”的“l”上,就好像我决定中止并且不再继续编辑该行:

$  weird -cmd ^Cne
$  stty -echoctl
$  weird -cmd line
$  # nice but now it looks like it got exec'd

这似乎是这个 stty echoctl 选项的主要作用。

我刚刚意识到, Press 是akaEscape的缩写。因此,tty 立即 ECHO ^[ 字符而不等待序列是合乎逻辑的。正常 echoctl 打开后,Home 键会生成.没有 echoctl ie after ,Home 键...放置光标control-[^[sleep^[[Hstty -echoctl左上方我的 xterm 屏幕!

(当 bash 唤醒时,Home 键起作用:行首。)

这两bind -p行是builtin/terminfo xterm:

"\eOH": beginning-of-line
"\e[H": beginning-of-line

相关内容