众所周知,当我们重新启动、关闭或启动系统时,屏幕上会打印一些消息,下面是一个捕获:
我的系统是 Ubuntu 16.04,我知道上面的这些日志消息来自 systemd。
据我了解,普通的用户进程可以在屏幕上打印内容,因为系统给了它三个文件描述符:0、1和2。我们可以在/proc/<PID>/fd/
.这是一个例子:
root@X86-Xenial-6:~# ls /proc/3467/fd
0 1 2 255
这3467
是一个 hello-world 程序,我不知道是什么,但225
我知道0
和是标准输入、标准输出和标准错误。1
2
所以,我有一个问题:当系统开始关闭、重新启动或启动时,用户进程尚未创建或已被销毁,这意味着它/proc/
不再存在,在这种情况下,0
,1
并且2
不存在。
那么为什么来自 systemd 的消息可以打印在屏幕上呢?内核可以打印东西,因为它立即控制屏幕,但我不认为systemd属于内核,那么它怎么能在屏幕上打印东西呢?使用什么样的函数或者api?
答案1
启动和关闭主要在用户空间中进行,而不是由内核进行。一旦内核完成初始化,它就会init
像常规进程一样查找并启动该进程,并使用指向控制台的标准文件描述符。因此init
(在您的情况下,initramfs 脚本然后是 systemd)可以写入其标准输出,并且它写入的任何内容都将显示在屏幕上(或控制台输出配置为显示的任何位置)。这种情况一直持续到内核关闭或重新启动为止,这种情况发生在用户空间关闭之后(并且在所有关闭日志都已写入控制台之后)。
顺便说一句,请注意,这/proc
只是访问内核维护的某些信息的一种方法;无论/proc
是否安装,这些信息都存在。
还要注意的是
众所周知,当我们重新启动、关闭或启动系统时,屏幕上会打印一些消息
不一定是真的——许多系统现在启动和关闭时不显示日志,所以我们不能假设“我们都知道”。
答案2
一个简短的回答,以消除一些误解。
- 该过程是在用户空间中完成的:特别是
init
第一个用户进程。 - 您不需要 /proc 来使文件描述符存在。如果访问文件描述符的唯一方法是通过文件,那么如何访问文件描述符? (您将打开文件以
/proc
返回文件描述符,尝试在/proc
返回文件描述符中查找它......)。/proc
只是一个视图,只有报告其他进程的进程才需要它。 - 在您的示例中,255 个文件描述符
ls
属于目录/proc/3467/fd
:ls
必须打开该目录,因此我们需要一个额外的文件描述符。我们有一个额外的,所以就是这样。 /proc/fd/1
等指向其他设备。例如1 -> /dev/pts/3
。做一个ls -l /proc/self/fd
- 当内核启动时,
init
它将把它的 stdin、stdout、stderr 连接到屏幕(一个 tty 设备,渲染到屏幕上)或其他地方。 init
是进程1
(在您的系统上systemd
)。