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*
终端上的某些内容进行交互?
/dev/pts/10
是伪终端设备对的从端。另一端是打开主克隆设备/dev/ptmx
并/dev/pts/10
成对接收的程序(每次打开/dev/ptmx
,您都会获得不同的从设备)。/dev/ptmx
和之间的连接/dev/pts/10
基本上是一个带有扭曲的双向管道。
当您打开终端模拟器应用程序时:
/dev/ptmx
并获取另一端的名称。它配置另一端并打开它,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/*
从中读取的所有内容都来自连接到终端的输入设备,/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)
归档时间: |
|
查看次数: |
1070 次 |
最近记录: |