为什么终端有时会回显特殊字符,例如 ^C?

为什么终端有时会回显特殊字符,例如 ^C?

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

^C

尽管信号已传递到应用程序(并且可能是由终端处理的密钥)。为什么角色会出现回响?

答案1

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

stty -ctlecho

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

man stty | less +/ctlecho

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

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

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

答案2

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

stty -echoctl # turn echoctl off
stty echoctl  # turn echoctl on

您可以参考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( ^?)。就像所有其他人一样,顺便说一句;-)

答案3

Unix 风格的终端连接最初是为慢得多(9600 bps 甚至更低)的连接而开发的,可能是通过拨号调制解调器线路进行的,这可能会导致传输错误。在任何应用程序获取输入之前,回显功能由 TTY 驱动程序生成,尽管应用程序可能会在必要时禁用回显功能。

当连接到负载较重的服务器和/或通过慢速连接时,所有字符的回显将为您提供反馈,表明字符已正确接收。因此,当您看到 时^C,您就会知道远程计算机已正确接收您的Ctrl+按键。C如果没有立即得到进一步答复,您现在就会知道问题不在于通信。

例如,系统可能太忙而无法立即显示新的命令提示符;或者,被中断的程序或脚本可能有一个 SIGINT 处理程序,该处理程序要么在退出之前执行一些操作(例如备份任何未保存的数据),要么完全忽略中断信号。

相关内容