![为什么终端有时会回显特殊字符,例如 ^C?](https://linux22.com/image/12581/%E4%B8%BA%E4%BB%80%E4%B9%88%E7%BB%88%E7%AB%AF%E6%9C%89%E6%97%B6%E4%BC%9A%E5%9B%9E%E6%98%BE%E7%89%B9%E6%AE%8A%E5%AD%97%E7%AC%A6%EF%BC%8C%E4%BE%8B%E5%A6%82%20%5EC%EF%BC%9F.png)
当我从终端运行 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
、 、NL
、START
、之外的终端特殊字符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] 这个描述不太准确:
它不是以插入符号形式回显的“终端特殊字符”,而是控制字符(ASCII
0x0 - 0x1f
和0x7f
),无论它们是否特殊。如果您定义Q
为VINTR
“终端特殊字符”(替换默认的^C
,例如用stty intr Q
),它仍然会简单地回显为Q
,而不是^Q
或chr(0x91)
。在 Linux 上,当设置了该标志时,
VEOF
不会回显(作为^D
或以任何其他形式) 。ICANON
但它将要在这种情况下,在 *BSD 和 MacOS 上也会得到回应。ASCII
0x7f
(DEL
) 不会显示为char + 0x40
(如所述),而是显示为char ^ 0x40
(^?
)。就像所有其他人一样,顺便说一句;-)
答案3
Unix 风格的终端连接最初是为慢得多(9600 bps 甚至更低)的连接而开发的,可能是通过拨号调制解调器线路进行的,这可能会导致传输错误。在任何应用程序获取输入之前,回显功能由 TTY 驱动程序生成,尽管应用程序可能会在必要时禁用回显功能。
当连接到负载较重的服务器和/或通过慢速连接时,所有字符的回显将为您提供反馈,表明字符已正确接收。因此,当您看到 时^C
,您就会知道远程计算机已正确接收您的Ctrl+按键。C如果没有立即得到进一步答复,您现在就会知道问题不在于通信。
例如,系统可能太忙而无法立即显示新的命令提示符;或者,被中断的程序或脚本可能有一个 SIGINT 处理程序,该处理程序要么在退出之前执行一些操作(例如备份任何未保存的数据),要么完全忽略中断信号。