
眾所周知,當我們重新啟動、關閉或啟動系統時,螢幕上會列印一些訊息,以下是一個捕獲:
我的系統是 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
)。