什么负责将 /dev/pts/10 与 stdout/stdin/stderr 连接?

The*_*eer 1 linux shell tty

tty在终端中的 a上运行命令时,它返回/dev/pts/10

除此之外还有文件/dev/stdout /dev/stdin/dev/stderr. 直接与他们互动会在终端中显示结果。

user@laptop:build$ tty
/dev/pts/10
user@laptop:build$ echo "Test" > /dev/stdout
Test
user@laptop:build$ echo "Test" > /dev/stdin
Test
user@laptop:build$ echo "Test" > /dev/stderr
Test
Run Code Online (Sandbox Code Playgroud)

同时,任何CLI应用程序,从shell启动,将有描述打开文件stdout/ stderr/ stdin。即,如果您运行打印某些内容的脚本,则打印相当于写入stdout.

到目前为止stdout/ stderr/stdin是唯一的接口shell工作与。应用程序也是如此。

某些操作系统组件最终会移动写入stdout终端的数据,否则我将看不到任何打印内容。

stdout/stdin/stderr终端之间的连接何时何地发生,以便与std*终端上的某些内容进行交互?

我想挑战的粗略假设是:

/dev/stdout,/dev/stdin并且/dev/stderr由正在运行的 shell 创建,它们在没有 shell 的情况下不存在。

Shell 使用代表终端的实际设备文件 ( /dev/pts/10)建立通信通道/dev/stdout/dev/stdin并通过、和公开终端功能/dev/stderr。通过这种方式,shell 为应用程序提供了一个简单的文件界面,而不是让每个应用程序担心如何处理设备文件以进行简单的打印。

更新

即使/dev/pts/10是一个伪终端,我也会更重视在不引入伪终端概念的情况下设法给出答案的答案。我从一个角度来看,它只会分散对问题答案的注意力:

stdout/stdin/stderr终端之间的连接何时何地发生,以便与/dev/std*终端上的某些内容进行交互?

Pio*_*asz 5

/dev/pts/10伪终端设备对的从端。另一端是打开主克隆设备/dev/ptmx/dev/pts/10成对接收的程序(每次打开/dev/ptmx,您都会获得不同的从设备)。/dev/ptmx和之间的连接/dev/pts/10基本上是一个带有扭曲的双向管道。

当您打开终端模拟器应用程序时:

  • 它打开/dev/ptmx并获取另一端的名称。它配置另一端并打开它,
  • 它分叉,
  • 新进程打开伪终端设备的另一端并将其stdinstdoutstderr 连接到它,
  • 新进程执行shell。

shell 不设置这三个文件描述符,它从其父进程继承它们。与它的子节点从 shell 继承文件描述符的方式相同。

备注:在 Linux 系统上/dev/stdin/dev/stdout/dev/stderr是真实文件,通过一系列符号链接指向/proc/<pid>/0,/proc/<pid>/1/proc/<pid>/2,然后又指向真实的输入/输出设备:在您的情况下/dev/pts/10

这三个标准流的存在由 C 库保证。

编辑:为了解决您更新的问题,让我们澄清答案的一些要点:

  • 写入的所有/proc/pts/*内容都由创建它并显示的终端读取,/proc/pts/*从中读取的所有内容都来自连接到终端的输入设备,
  • 在 Linux/dev/stdout上通常是指向 的符号链接/proc/self/fd/1,而/dev/stdin指向/proc/self/fd/0. 虚拟/proc文件系统负责向每个应用程序显示/proc/self一个指向 的符号链接/proc/<pid><pid>应用程序进程 ID在哪里。
  • 符号链接/proc/<pid>/fd指向由应用程序打开或从其父级继承的文件、管道和其他内容。每个应用程序都保证打开三个文件描述符:0读取输入、1写入输出、2写入错误。在你的情况下是/dev/pts/10

如果您不将输出重定向到另一个文件,shell 运行的每个命令都会写入终端。此规则的例外情况是,如果您的命令的进程组与终端的前台进程组不同,则写入将失败SIGTTOU并将被发送到命令。可以使用stty tostop和控制此行为stty -tostop

stty tostop
echo "/dev/stdout points to the terminal, but I won't print anything" &
stty -tostop
echo "You can see me" &
Run Code Online (Sandbox Code Playgroud)