我最近tail -f
在运行的服务器的日志文件上运行,试图诊断错误,当时我不小心碰到了键盘并输入了一些字符。它们与日志的输出混合在一起,无法区分哪个是哪个。我已经无数次经历过类似烦人的事情,而且我确信这里的许多其他人也发生过这种情况。
所以我的问题是这样的:为什么 shell(或终端,或任何执行此操作的程序)会模糊地混合键盘输入和命令输出?
我并不是要求针对眼前的问题提供实际的解决方案。我也许可以找到某种方法让 shellstty -echo
在命令运行时和stty echo
完成时运行。但我想知道这样设计终端的基本原理。有什么实际目的吗?或者只是出于兼容性原因而做的事情,或者根本没有考虑太多?
答案1
人们通常希望看到他们正在输入的内容(除非是密码):-)
终端随时接受输入,并对其进行缓冲,直到应用程序读取它。不仅如此,当 tty 处于煮熟的模式,内核一次缓冲整行并提供一些基本的行编辑功能,允许您删除整个缓冲行(默认绑定Ctrl-u和退格键)。在输入和编辑行期间,直到您按下Enter,从终端读取的应用程序都不会读取任何内容。
内核中的 tty 功能不知道也不可能知道像这样的应用程序是否以及何时tail
计划在终端上生成输出,因此它无法以某种方式...取消(?)在这种情况下并且仅在这样的时候。
不管怎样,当终端上还有其他东西正忙着运行并且 shell 还没有准备好读取该命令时,能够为 shell 准备下一行是一个特征,不是一个错误,所以我不主张删除它。也许不太有用tail
(它永远不会自行终止),但在长时间运行期间预先键入下一个命令cp
或make
(例如),甚至使用Ctrl-h和Ctrl-编辑该命令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 设备读取数据的应用程序执行此操作。