c - 终端如何从标准输出读取并在屏幕上绘制文本?

标签 c linux macos bash unix

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

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

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

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

谢谢!

最佳答案

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

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

COMMAND   PID USER   FD   TYPE DEVICE  SIZE/OFF     NODE NAME
...
cat     52919 user    0u   CHR   16,5    0t4562     3313 /dev/ttys005
cat     52919 user    1u   CHR   16,5    0t4562     3313 /dev/ttys005
cat     52919 user    2u   CHR   16,5    0t4562     3313 /dev/ttys005

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

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

伪终端设备是使用 forkpty() libc 函数创建的。这在幕后如何工作的细节因平台而异,而且可能会非常复杂,所以我不会深入探讨细节。

关于c - 终端如何从标准输出读取并在屏幕上绘制文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15938518/

相关文章:

regex - 根据 Linux 中文件的数量重命名目录

python - 如何忽略 SIGKILL 或强制进程进入 'D' sleep 状态?

cocoa - 当进程或应用程序被终止/强制终止时收到通知吗?

c++ - 菜单栏仅在使用 Qt5 在 MacOS 上切换应用程序/桌面后显示

c - 如何释放带有指针的链表

c - 如何在c中创建给定代码的表?

c - C删除数组中的重复项

android - Cordova 错误 : Failed to find 'ANDROID_HOME' environment variable

c - 用于峰值 EQ 的 IIR 系数,如何将它们传递给 vDSP_deq22?

c - 为什么 Linux VmSize VmData 比代码估计的要大?