Unix中的echo命令是如何工作的?

4
当我按下任何一个键时,通常立即回显到标准输出,也就是我的屏幕上。
如果我必须输入密码,那么它会说不会回显,我看不到我输入的键。
这是如何工作的?
每个按键是否立即进入内核(在我按下ENTER键之前),然后内核决定是否回显它们? 例如,我按下'A',它进入内核;内核回显它;我在屏幕上看到它。现在我按下'B'...同样的序列再次发生...;现在我在屏幕上有了'AB' (我的命令) 并按下ENTER键; 我的命令被发送到内核并最终执行。
还有其他解释吗?在按键期间背景中发生了什么?

1
你的命令由Shell解释,而不是内核。 - Srinivas Reddy Thatiparthy
混淆stdout和屏幕是一个错误。stdout不是你的屏幕。stdin也不是你的键盘。有时,进程的stdout流与屏幕相关联。有时,stdin与键盘相关联。但它们并不相同。停止认为它们是相同的。 - William Pursell
@Reddy。是的。我知道命令是由shell解释的。我说的是按键。 - dams
@Pursel。这就是为什么我写了“即我的屏幕”,因为标准输出也可以是一个文件。 - dams
3个回答

5
内核中的终端驱动程序可以处于几种模式(实际上有许多更多的标志,而这些天“cbreak”实际上是与不同标志相反的,因此这是简化的)。
“cbreak”模式意味着试图从终端读取的进程将在可用时立即接收键盘输入。当cbreak模式关闭时,数据由内核存储在缓冲区中,直到按下回车键,某些键如退格键由内核处理(当您按下退格键时,它会从缓冲区中删除字符并且如果回显模式打开,则在终端上写入“退格-空格-退格”以用空格覆盖字符)。
回显模式意味着每当用户按下键时,内核将立即将其回显到屏幕上。当它关闭时,不会回显任何内容到屏幕上,并且程序需要将其写入终端,如果要让您看到它。
有几种典型情况:
- 在进行高级输入处理的程序中(例如大多数shell或类似全屏程序的东西),cbreak开启,echo关闭;如果字符不是特殊键转义序列的一部分,则程序将自己将字符写入终端。 - 在大多数情况下[使用简单程序读取stdin并写入stdout的默认情况下],echo开启,cbreak关闭。当您键入时,它会像我上面描述的那样处理,所有这些都由内核处理,直到您按下回车并将其发送给应用程序。输入编辑仅限于退格[和ctrl-u、ctrl-w],尝试使用箭头键只会在输入行中放置类似于^[[D的转义序列。 - 在读取密码时,echo关闭,cbreak关闭。输入的工作方式与默认情况相同,除了内核不会将输入复制到屏幕上。
正在运行的程序使用termios函数告诉内核处于哪种模式。您可以使用stty命令在shell环境中执行相同的操作,但请注意,这可能会干扰shell自己的输入处理或运行程序所期望的默认状态。

如果回显模式打开,则写入“退格-空格-退格”:请问您能解释一下吗?为什么不直接向终端输出“退格”呢?额外的“空格-退格”有何意义? - dams
@dams 打印一个退格符只是将光标向左移动,而不会擦除字符。 - Random832

1

你的键盘会产生电信号,最终被解释为对应字母-'A'、'B'、功能键F1、F2等的按键码。这一切都发生在由内核处理的键盘驱动程序中。该键盘驱动程序具有缓冲区,用于接收来自键盘的所有按键,并将其发送到内核,然后将它们直接传递给当前拥有焦点的进程。如何处理按键序列完全由各个应用程序决定,例如是否显示按键。


-1

echo程序是coreutils的一部分。您可以在这里下载其源代码。查看src/echo.c,它非常小。您可以看到echo使用fputcputchar调用。这些调用处理称为stdout的标准流。标准流的架构非常复杂,超出了本帖子的范围。您可以使用例如google找到它。


啊,我错过了什么。请原谅我。 - maverik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接