为什么命令运行时终端会回显击键?

为什么命令运行时终端会回显击键?

我最近tail -f在运行的服务器的日志文件上运行,试图诊断错误,当时我不小心碰到了键盘并输入了一些字符。它们与日志的输出混合在一起,无法区分哪个是哪个。我已经无数次经历过类似烦人的事情,而且我确信这里的许多其他人也发生过这种情况。

所以我的问题是这样的:为什么 shell(或终端,或任何执行此操作的程序)会模糊地混合键盘输入和命令输出?

我并不是要求针对眼前的问题提供实际的解决方案。我也许可以找到某种方法让 shellstty -echo在命令运行时和stty echo完成时运行。但我想知道这样设计终端的基本原理。有什么实际目的吗?或者只是出于兼容性原因而做的事情,或者根本没有考虑太多?

答案1

人们通常希望看到他们正在输入的内容(除非是密码):-)

终端随时接受输入,并对其进行缓冲,直到应用程序读取它。不仅如此,当 tty 处于煮熟的模式,内核一次缓冲整行并提供一些基本的行编辑功能,允许您删除整个缓冲行(默认绑定Ctrl-u和退格键)。在输入和编辑行期间,直到您按下Enter,从终端读取的应用程序都不会读取任何内容。

内核中的 tty 功能不知道也不可能知道像这样的应用程序是否以及何时tail计划在终端上生成输出,因此它无法以某种方式...取消(?)在这种情况下并且仅在这样的时候。

不管怎样,当终端上还有其他东西正忙着运行并且 shell 还没有准备好读取该命令时,能够为 shell 准备下一行是一个特征,不是一个错误,所以我不主张删除它。也许不太有用tail(它永远不会自行终止),但在长时间运行期间预先键入下一个命令cpmake(例如),甚至使用Ctrl-hCtrl-编辑该命令u,所有这些都在 shell 获取之前这是一件很常见的事情。蒂莫西·马丁写在一条评论:

值得一提的是,它less +F somefile提供了类似的功能,tail -f somefile只是(意外地)键入的击键不会echo出现在屏幕上。

是的,但less不仅可以防止这些字符被回显,而且还可以它们,因此下一个想要读取它们的应用程序无法使用它们!

最后,还有一个原因:

在历史时期(在我的时代之前!)具有本地回显功能的终端很常见。也就是说,终端(通常在硬件中)将回显您在本地键入的字符,同时还将它们发送到串行线路。即使与 UNIX 系统的连接存在大量延迟,这对于为用户提供快速反馈很有用(想想300 波特率调制解调器通过自动远程登录将终端服务器拨号到慢速 UNIX 系统令牌环网络——或者其他什么)。

如果您有一个带有本地回显的终端,那么您需要stty -echo始终在您所连接的 UNIX 服务器上。结果与 terminak 大致相同没有本地回显(当今常见的一种)并stty echo启用。因此,从这个角度来看,stty echo的工作是在收到字符后立即回显字符,无论正在运行什么软件,以模拟具有本地回显的终端上会发生的情况。

(顺便说一句,如果你有一个带有本地回显的终端,你就无法隐藏你的密码。)

答案2

使用zsh,如果您想禁用echo特定命令的本地 tty 设备,您可以执行以下操作:

STTY=-echo a-specific-command

zsh将应用特定设置(通过调用stty)并在命令终止时恢复它们。

当然,您可能只想对不从 tty 设备读取数据的应用程序执行此操作。

相关内容