【问题标题】:How does Terminal read from stdout and draw the text on-screen?终端如何从标准输出读取并在屏幕上绘制文本?
【发布时间】:2013-04-03 01:00:50
【问题描述】:

我有一个关于终端和进程如何工作的一般性问题。

从任何进程中,如果我写入标准输出(即文件描述符 2),它就会被绘制在终端窗口上。我的问题是,这实际上是如何实现的? stdout 是否是终端不断读取并在屏幕上绘制内容的实际“虚拟”文件?或者进程/标准输出流和终端之间是否存在某种 IPC?

请注意,当我说终端时,我指的是一些通用的 GUI 终端/控制台,例如 Mac 上的终端。

附:如果这个问题不清楚,请告诉我,我很乐意再次尝试解释:)

谢谢!

【问题讨论】:

  • Unix 的天才(?)是一切都是文件、设备和一切。
  • Stdout 是文件描述符 1。Stdin 是 0,stderr 是 2

标签: c linux macos bash unix


【解决方案1】:

当你包含 stdio.h 时,stdout 是一个在那里定义的变量。

引用Wikipedia

stdout - 指向标准输出流的 FILE 的指针,通常是显示终端

而且,正如 Russ C 所提到的,在 Unix 中一切都是文件,所以在这方面你是对的。

apparently,每个打开的 unix 程序都将其输出、输入和错误流默认设置为 stdout、stdin 和 stderr。不过,它们可以更改。就像在终端中 redirect 使用'这样的语句中这样做

mysql -u root -p dbname < ./data.sql

我想这并不能真正回答你关于实现的真正细节的所有问题,但知道它是一个文件流可能会让你对正在发生的事情有一个很好的了解。

【讨论】:

    【解决方案2】:

    您似乎没有意识到的神奇部分是内核的 tty 层。

    您打开的每个终端窗口都对应一个 pseudoterminal device — 例如,/dev/ttys001 是 Mac OS X 上此类设备的名称。默认情况下,任何在终端中运行且没有其输入/输出从/到其他地方重定向,其标准输入、输出和错误都设置为这些设备之一。例如,如果我在终端中运行的cat 进程上运行lsof,我会看到:

    命令 PID 用户 FD 类型 设备尺寸/关闭节点名称 ... 猫 52919 用户 0u CHR 16,5 0t4562 3313 /dev/ttys005 猫 52919 用户 1u CHR 16,5 0t4562 3313 /dev/ttys005 猫 52919 用户 2u CHR 16,5 0t4562 3313 /dev/ttys005

    当一个进程写入一个伪终端从设备时,输出被路由到持有连接的主端的进程(在这种情况下,你的终端应用程序),它可以读取它。类似地,当终端应用程序写入伪终端主设备时,数据可供任何从相应从设备读取的进程使用。

    伪终端设备还涉及其他一些技巧。最值得注意的是,它们具有固有的行和列大小,在其中运行的应用程序可以查询,它们可以对通过它们的数据执行某些简单的转换(例如,CR 到 CR/LF,退格到 DEL 等事物),并且它们可以在看到某些字符时生成信号(例如,Ctrl-C 向前台进程生成中断信号)。这里有很多奇怪的历史细节,但关键是内核的 tty 层是大多数这种行为存在的地方。

    伪终端设备是使用forkpty() libc 函数创建的。这在幕后如何运作的细节因平台而异,并且可能会变得很复杂,所以我不会深入研究细节。

    【讨论】:

      【解决方案3】:

      这是大图。

      1. 终端是一个设备。它是一个硬件,您可以通过向其硬件接口写入数据来使事物出现在其上。
      2. 操作系统将此(以及任何硬件设备)的处理委托给设备驱动程序。设备驱动程序本质上为设备提供了一个软件接口。然后,您可以通过调用此设备驱动程序软件接口使内容出现在终端上。
      3. 在 *nix 系统中,设备驱动程序将它们控制的硬件设备公开为文件系统中的文件。您可以打开这些文件,并调用设备驱动程序提供的软件接口(通过 open、ioctl、close 等)。
      4. C 库有一个分层 I/O 系统,它在下面打开这些文件并代表您调用设备驱动程序接口。您也可以自己做,但要知道您使用的任何库函数也都在做。
      5. 默认情况下,创建进程时,描述符 0 和 1 会在终端设备上打开。因此,当您写入这些描述符时,底层驱动程序会接收数据,并与硬件设备对话以在屏幕上呈现字符。
      6. 当您将一个进程的输出通过管道传输到另一个进程或将输出重定向到一个文件时,描述符会重新打开到其他设备(如管道或文件),您写入它们的数据最终会在相应的设备驱动程序,最后是硬件设备。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-16
        • 2010-09-09
        • 2023-03-26
        相关资源
        最近更新 更多