众所周知,当我们重新启动、关闭或启动系统时,屏幕上会打印一些消息,下面是一个截图:
我的系统是 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?
启动和关闭主要是在用户空间中进行的,而不是由内核进行的。一旦内核完成初始化,它就会
init
像一个常规进程一样查找并启动它,标准文件描述符指向控制台。因此init
(在您的情况下,initramfs 脚本,然后是 systemd)可以写入其标准输出,并且它写入的任何内容都将显示在屏幕上(或控制台输出配置为显示的任何位置)。这种情况一直持续到内核关闭或重新启动,这发生在用户空间关闭之后(并且在所有关闭日志都已写入控制台之后)。顺便说一句,请注意这
/proc
只是访问内核维护的某些信息的一种方式;/proc
无论是否安装,这些信息都存在。还要注意
不一定正确——许多系统现在启动和关闭时不显示日志,所以我们不能假设“我们都知道”。
简短的回答,以澄清一些误解。
init
是第一个用户进程。/proc
返回文件描述符中打开文件,尝试在返回文件描述符中查找它/proc
......)。/proc
只是一个视图,只有报告其他进程的进程才需要它。ls
您示例中的 255 文件描述符是目录/proc/3467/fd
:ls
必须打开目录,因此我们需要一个额外的文件描述符。我们有一个额外的,所以就是这样。/proc/fd/1
等指向其他设备。例如1 -> /dev/pts/3
。做一个ls -l /proc/self/fd
init
,它将其标准输入、标准输出、标准错误连接到屏幕(一个 tty 设备,它被渲染到屏幕上),或者连接到其他地方。init
是进程1
(在您的系统上systemd
)。