【问题标题】:How messages from printf are routed to the terminal?来自 printf 的消息如何路由到终端?
【发布时间】:2016-07-14 15:08:25
【问题描述】:

假设我在 konsole 中打开了两个选项卡(Tab1 和 Tab2)。

当我在他们两个中运行 tty 时,我有:

Tab1:

~$ tty
/dev/pts/23

Tab2:

~$ tty
/dev/pts/24

如果我在 Tab1 中运行带有 printf("Hello") 的简单程序 hello.c,系统如何从写入 stdout(文件 id 1)到写入 /dev/pts/23,被读取konsole 然后出现在 Tab1 中?

系统如何知道它必须将“Hello”字符串提供给 /dev/pts/23 而不是 /dev/pts/24?它是如何做到的?

bash 是否给程序提供了一个参数,以便它知道哪个伪终端发送“Hello”?或者程序将字符串发送回 bash(如何?)谁知道将数据发送到哪个伪终端?

感谢您的帮助

【问题讨论】:

  • 打开的文件集对于每个进程都是本地的。 shell 在 stdin/out/err 插槽中打开了一个特定的伪终端设备,该设备在生成时由子进程继承。伪终端本身本质上是一个由系统调用分配的命名管道,x 终端或您正在使用的任何终端正在从另一端读取文本并打印到屏幕上。 This is a good read 顺便说一句。

标签: stdout pty terminal-emulator


【解决方案1】:

如果您查看您的进程打开文件,您可以看到 STDOUT、STDERR 等指向您已经在问题中使用 tty 找出的特定伪终端

root@hello:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 May 21 02:18 0 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 1 -> /dev/pts/3
lrwx------ 1 root root 64 May 21 02:18 2 -> /dev/pts/3

您可能知道,一个进程是由fork 系统调用创建的,该系统调用实际上复制了父级的打开文件描述符。所以基本上,您的进程从其父进程获取文件描述符。

父母是怎么把这些和他联系起来的?好吧,konsole 已经处理好了。

【讨论】:

  • 感谢您的回答。当我执行 ls -l /proc/self/fd 时,内核如何知道我从哪个终端进行此调用?为什么每个 konsole 选项卡的输出都不同?
  • 在网上搜索controlling terminal。从这里开始:gnu.org/software/libc/manual/html_node/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-25
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多