为什么终端有时会回显像 ^C 这样的特殊字符?

loc*_*ocu 6 terminal keyboard

当我从终端运行 GUI 程序并输入Ctrl+ 时C,我会从终端收到回显:

^C
Run Code Online (Sandbox Code Playgroud)

尽管信号被传送到应用程序(并且大概是由终端处理的密钥)。?为什么会回显字符?

Gil*_*not 6

运行这个,它只是一个终端设置,默认情况下,你输入的所有内容都会被回显:

stty -ctlecho
Run Code Online (Sandbox Code Playgroud)

现在,您的终端设置为不显示这些字符。

man stty | less +/ctlecho
Run Code Online (Sandbox Code Playgroud)

[-]ctlecho
以帽子符号('^c')回显控制字符

要永久保留此配置,请将其添加到 *rc 文件中。(~/.bashrc或类似)。

要列出stty设置,只需单独键入命令。

  • 问题不是_如何关闭回声?_不过。这是_为什么要回显字符?_,这个答案实际上并没有给出答案,让提问者_推断_一个未说明的答案,甚至没有“规范”这个词作为线索。 (11认同)

小智 4

该字符会回显,因为您ECHO在终端设置中打开了该标志,并且以 ^C 形式回显,因为您打开了该ECHOCTL标志。在大多数系统上,这两个标志都默认打开。您可以通过使用小写形式的实用程序来打开和关闭它们stty(1)

stty -echoctl # turn echoctl off
stty echoctl  # turn echoctl on
Run Code Online (Sandbox Code Playgroud)

您可以参考termios(3)Linux 上的联机帮助页了解说明 [1]:

ECHOCTL(不在 POSIX 中)

如果ECHO同时设置TAB,则除、 、NLSTART、之外的终端特殊字符STOP将回显为^X,其中是 ASCII 码 大于特殊字符的X字符 。0x40例如,字符0x08( BS) 将回显为^H。[需要_BSD_SOURCE_SVID_SOURCE]

请注意,关闭标志ECHOCTL不会阻止控制字符回显,但会导致它们以其原始形式而不是插入^X符号形式回显。字符是特殊的并且会生成信号(例如^C-> VINTR-> SIGINT)这一事实不会以任何方式影响它是否会被回显。

大多数终端模拟器不会以任何方式显示控制字符(不幸的是),但它们可能会以有趣的方式解释它们:作为说明性示例,启动类似 sleep 3600或 的命令cat > /dev/null,然后在下一行按按键<Escape>[41m foo<Enter>。打开echoctl后,您将^[[41m foo在屏幕上打印,并且不会发生任何特殊情况。但如果echoctl关闭,终端会将回显解释<Raw_esc>[41m为 ANSI 颜色转义(不显示任何[41m等),并将背景变成红色。

根据终端仿真器及其设置,emacs 用户^N通过反射按下可能最终会切换到备用字符集,并将所有字母变成线条画花体。

您通常不希望这些发生,因此ECHOCTL可以被视为合理的默认值。


[1] 这个描述不太准确:

  • 它不是以插入符号形式回显的“终端特殊字符”,而是控制字符(ASCII0x0 - 0x1f0x7f),无论它们是否特殊。如果您定义QVINTR“终端特殊字符”(替换默认的^C,例如用stty intr Q),它仍然会简单地回显为Q,而不是^Qchr(0x91)

  • 在 Linux 上,当设置了该标志时VEOF,不会回显(作为^D或以任何其他形式) 。ICANON但在这种情况下,它也会在 *BSD 和 MacOS 上得到回应。

  • ASCII 0x7f( DEL) 不会显示为char + 0x40(如所述),而是显示为char ^ 0x40( ^?)。就像所有其他人一样,顺便说一句;-)