为什么点击 TTY 设备只能捕获所有其他字符?

为什么点击 TTY 设备只能捕获所有其他字符?

所以,我遇到了这个ttyname函数(unistd.h)并且必须对其进行测试。

#include <unistd.h>
#include <stdio.h>

int main(void) {
  printf("%s\n", ttyname(0));
  return 0;
}

在我的机器上,它回响了/dev/ttys011。我发现这是一个设备!

echo "Hello" > /dev/ttys011

哇哦,从另一个生成的终端运行它你好在我运行程序的原始终端中ttyname

那么当我这样做时会发生什么呢cat /dev/ttys011?好吧,我明白了所有其他角色键入。哦耶;它也破坏了原来的 TTY 会话。

所以我尝试以下操作:

cat /dev/ttys011 | tee /dev/ttys011

好吧,一切出现在原始终端中,但我的“tap”终端(运行上述命令的终端)仍然只得到所有其他角色

哦,是的,我原来的终端仍然坏了(字符出现了,但只有其他字符真正到达了我的 shell)。

例如,在终端中的“tap”终端中输入lsYield ,然后运行它会得到.lsl'l' is not a command

这里发生了什么?我预计会有奇怪的行为,但为什么所有其他角色被俘虏?

答案1

您的 shell,或者前台的任何进程,已经在读取所连接的终端,即/dev/ttys011.然后你开始了另一个进程,一个cat 同时读取同一终端。

现在有两个进程竞争来自终端的相同输入。每次您在终端中键入一个密钥时,它都会被传递到其中一个等待进程。另一个进程也有兴趣阅读,但是当轮到它阅读时,就没有什么可读的了。尽管您似乎观察到哪些字符进入哪个进程的定期交替,但实际上无法预测输入的哪些部分将进入哪个进程:它可能是一个进程的所有输入,另一个进程的所有输入,或者介于两者之间的任何内容。

如果您希望cat进程接收所有输入,则需要安排没有其他内容同时从同一设备读取。一种简单的方法是sleep 999在终端中运行类似的命令。sleep等待延迟到期,但在等待期间它不应该尝试读取任何内容。

命令:

cat /dev/ttys011 | tee /dev/ttys011

不会将捕获的任何输入恢复cat到其原始位置。也就是说,tee不会将其传递到最初有兴趣读取它的任何进程(例如您的 shell),它只是将其发送到终端的输出,从而导致其显示。

顺便说一句:您不需要 C 程序和ttyname()函数来获取终端名称;您所要做的就是tty在 shell 提示符下键入并按 Enter 键。

相关内容