# 練習 15:系統啟動:運行級別,`/etc/init.d`,`rcconf`,`update-rc.d`
> 原文:[Exercise 15. System boot: runlevels, /etc/init.d, rcconf, update-rc.d](https://archive.fo/kQr60)
> 譯者:[飛龍](https://github.com/wizardforcel)
> 協議:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/)
> 自豪地采用[谷歌翻譯](https://translate.google.cn/)
首先我會給出一個典型的系統啟動過程的概述:
```
你
按電源開關(或啟動虛擬機)
現在計算機獲得控制權
控制權傳給了 BIOS
BIOS
執行硬件特定的任務
執行開機自檢(POST),測試你的硬件
檢測安裝的硬件,如硬盤,內存類型和數量,...
通過將初始值寫入其內存來初始化硬件
找到一個啟動設備,通常是一個硬盤
讀取并執行位于此磁盤開頭的 MBR(主引導記錄)
控制權現在傳給了 MBR
MBR
MBR 尋找并執行 GRUB(多重操作系統啟動管理器)
控制權現在傳給了 GRUB
GRUB
查找可用的文件系統
查找并讀取其配置文件,來了解:
系統位于哪里
啟動什么系統
執行什么其他的操作
執行 Linux 內核,Linux 操作系統的主要部分
控制權現在傳給了 Linux 內核
Linux 內核
查找并加載 initrd,這是初始的 ram 磁盤
initrd 包含必要驅動程序,允許真實文件系統的訪問和掛載
掛載文件系統,它在 GRUB 配置文件中指定。
執行`/sbin/init`,一個啟動所有其他程序的特殊程序
控制權現在傳給了 init
init
查看`etc/inittab`來確定所需的運行級別
加載適合此運行級別的所有程序
加載來自`/etc/rc.d/rc2.d/`的所有程序,因為 2 是默認的 Debian 運行級別
啟動 SSH 和 TTY,以便你可以連接到你的計算機
啟動現在完成了
你
使用 SSH 連接到你的計算機
SSH 守護進程為你執行 bash shell
你現在可以輸入東西
你再次獲得控制權
```
現在我們只對“init”和“運行級別”階段感興趣,所以我將總結一下,系統如何啟動并自動啟動一些程序。首先,有一些術語??:
+ 守護進程 - 一直運行在后臺的程序。這意味著它不在乎你是否登錄系統,通常你不需要手動啟動它,因為它在計算機啟動時自動啟動。
+ 運行級別 - 系統運行模式。基本上,這只是一個數字,提供給`init`程序,它知道哪些守護程序與每個數字相關聯,并根據需要啟動并停止這些守護程序。
在 Debian 中有以下運行級別:
| ID | 描述 |
| --- | --- |
| S | 系統通電后會執行它 |
| 0 | 停止,這定義了當系統關閉時執行哪些操作。 |
| 1 | 單用戶模式,這是一種特殊的故障排除模式。在這種模式下,大多數守護進程不會自動啟動。 |
| 2~5 | 完全多用戶,配置的守護程序在此模式下啟動。 |
| 6 | 重啟,類似停止,但不是關閉系統而是重新啟動。 |
但是`init`怎么知道的?好吧,這是用于它的特殊目錄。
```
user1@vm1:/etc$ find /etc -type d -name 'rc*' 2>/dev/null | sort
/etc/rc0.d
/etc/rc1.d
/etc/rc2.d
/etc/rc3.d
/etc/rc4.d
/etc/rc5.d
/etc/rc6.d
/etc/rcS.d
```
你可能能猜到,每個數字和`S`對應表中的運行級別。讓我們列出其中一個目錄,它在正常啟動中啟動所有所需的守護進程。
```
user1@vm1:/etc$ ls -al /etc/rc2.d | awk '{printf "%-15.15s %-3.3s %s\n",$9,$10,$11}'
.
..
README
S14portmap -> ../init.d/portmap
S15nfs-common -> ../init.d/nfs-common
S17rsyslog -> ../init.d/rsyslog
S17sudo -> ../init.d/sudo
S18acpid -> ../init.d/acpid
S18atd -> ../init.d/atd
S18cron -> ../init.d/cron
S18exim4 -> ../init.d/exim4
S18ssh -> ../init.d/ssh
S20bootlogs -> ../init.d/bootlogs
S21rc.local -> ../init.d/rc.local
S21rmnologin -> ../init.d/rmnologin
S21stop-bootlog -> ../init.d/stop-bootlogd
```
如你所見,此目錄中的文件只是實際啟動腳本的符號鏈接。我們來看看其中一個鏈接:`S18ssh→../init.d/ssh`。這是關于這個文件的事情:
+ 它是一個`./init.d/ssh`文件的鏈接
+ 它以`S`開始,意味著“啟動”。Debian 啟動系統中使用的每個腳本至少有 2 個參數,“啟動”和“停止”。現在我們可以說,當我們的系統切換到運行級別 2 時,該腳本將使用動作“啟動”來執行 。
+ 它有一個數字 18。`rc`目錄中的腳本以字典序執行,所以現在我們明白,在啟動`ssh`之前 ,系統啟動`portmap`,`nfs-common`,`rsyslog`和`sudo`。`rsyslog`是一個系統日志守護程序,特別是`ssh`想要記錄誰在什么時候訪問系統,所以在啟動之前需要運行`rsyslog`。
現在,你將學習如何列出啟用的服務(守護程序),以及啟用和禁用服務(守護程序)。
## 這樣做
```
1: sudo aptitude install rcconf
2: ls -al /etc/rc2.d
3: sudo rcconf --list
4: sudo update-rc.d exim4 disable
5: ls -al /etc/rc2.d
6: sudo rcconf --list
7: sudo update-rc.d exim4 enable
8: ls -al /etc/rc2.d
9: sudo rcconf --list
```
## 你會看到什么
```
user1@vm1:/var/log$ sudo aptitude install rcconf
The following NEW packages will be installed:
rcconf
0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/23.9 kB of archives. After unpacking 135 kB will be used.
Selecting previously deselected package rcconf.
(Reading database ... 24239 files and directories currently installed.)
Unpacking rcconf (from .../archives/rcconf_2.5_all.deb) ...
Processing triggers for man-db ...
Setting up rcconf (2.5) ...
user1@vm1:/etc$ ls -al /etc/rc2.d
total 12
drwxr-xr-x 2 root root 4096 Jun 27 11:42 .
drwxr-xr-x 68 root root 4096 Jun 25 18:43 ..
-rw-r--r-- 1 root root 677 Mar 27 05:50 README
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo
lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd
lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron
lrwxrwxrwx 1 root root 15 Jun 27 11:42 S18exim4 -> ../init.d/exim4
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local
lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin
lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd
user1@vm1:/etc$ sudo rcconf --list
rsyslog on
ssh on
bootlogs on
portmap on
sudo on
nfs-common on
udev on
console-setup on
kbd on
exim4 on
keyboard-setup on
acpid on
cron on
atd on
procps on
module-init-tools on
user1@vm1:/etc$ sudo update-rc.d exim4 disable
update-rc.d: using dependency based boot sequencing
insserv: warning: current start runlevel(s) (empty) of script `exim4' overwrites defaults (2 3 4 5).
insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `exim4' overwrites defaults (0 1 6).
user1@vm1:/etc$ ls -al /etc/rc2.d
total 12
drwxr-xr-x 2 root root 4096 Jun 27 11:43 .
drwxr-xr-x 68 root root 4096 Jun 25 18:43 ..
lrwxrwxrwx 1 root root 15 Jun 27 11:43 K01exim4 -> ../init.d/exim4
-rw-r--r-- 1 root root 677 Mar 27 05:50 README
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo
lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd
lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local
lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin
lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd
user1@vm1:/etc$ sudo rcconf --list
rsyslog on
ssh on
bootlogs on
portmap on
sudo on
nfs-common on
udev on
console-setup on
kbd on
keyboard-setup on
acpid on
cron on
atd on
procps on
module-init-tools on
exim4 off
user1@vm1:/etc$ sudo update-rc.d exim4 enable
update-rc.d: using dependency based boot sequencing
user1@vm1:/etc$ ls -al /etc/rc2.d
total 12
drwxr-xr-x 2 root root 4096 Jun 27 11:43 .
drwxr-xr-x 68 root root 4096 Jun 25 18:43 ..
-rw-r--r-- 1 root root 677 Mar 27 05:50 README
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo
lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd
lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron
lrwxrwxrwx 1 root root 15 Jun 27 11:43 S18exim4 -> ../init.d/exim4
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local
lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin
lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd
user1@vm1:/etc$ sudo rcconf --list
rsyslog on
ssh on
bootlogs on
portmap on
sudo on
nfs-common on
udev on
console-setup on
kbd on
exim4 on
keyboard-setup on
acpid on
cron on
atd on
procps on
module-init-tools on
user1@vm1:/etc$
```
## 解釋
1. 安裝`rcconf`包,讓你輕松管理運行級別。
1. 打印包含運行級別 2 的啟動腳本的目錄。現在啟用了郵件服務器`exim4`。
1. 僅僅打印出相同運行級別的服務。請注意,由于它們被視為系統服務,因此存在多個未顯示的服務。`rcconf –list –expert`會把它們全部列出,以及更多的駐留在不同的運行級別上的服務。
1. 禁用郵件服務器`exim4`的自動啟動。
1. 打印出包括運行級別 2 的啟動腳本的目錄。`exim4`啟動腳本現在從`S18exim4`重命名為`K01exim4`。這意味著`exim4`進入此級別時已停止(被殺死)。如果`exim4`開始沒有運行,就沒有任何反應。
1. 打印運行級別 2 的服務。服務`exim4`現在已關閉。
1. 開啟`exim4`的自動啟動。
1. 再次打印包含運行級別 2 的啟動腳本的目錄,`exim4`再次啟動。
1. 打印運行級別 2 的服務。`exim4`的狀態變更為已啟動,和預期一樣。
## 附加題
+ 請閱讀 Debian 啟動過程:<http://www.debian.org/doc/manuals/debian-reference/ch03.en.html>
+ 嘗試這樣做:`aptitude install sysv-rc-conf`,`sysv-rc-conf -list`。閱讀`man sysv-rc-conf`。
- 笨辦法學 Linux 中文版
- 練習 0:起步
- 練習 1:文本編輯器,vim
- 練習 2:文本瀏覽器,少即是多
- 練習 3:Bash:Shell、.profile、.bashrc、.bash_history
- 練習 4:Bash:處理文件,pwd,ls,cp,mv,rm,touch
- 練習 5:Bash:環境變量,env,set,export
- 練習 6:Bash:語言設置,LANG,locale,dpkg-reconfigure locales
- 練習 7:Bash:重定向,stdin,stdout,stderr,<,>,>>,|,tee,pv
- 練習 8:更多的重定向和過濾:head,tail,awk,grep,sed
- 練習 9:Bash:任務控制,jobs,fg
- 練習 10:Bash:程序退出代碼(返回狀態)
- 練習 11:總結
- 練習 12:文檔:man,info
- 練習 13:文檔:Google
- 練習 14:包管理:Debian 包管理工具aptitude
- 練習 15:系統啟動:運行級別,/etc/init.d,rcconf,update-rc.d
- 練習 16:處理進程,ps,kill
- 練習 17:任務調度:cron,at
- 練習 18:日志:/var/log,rsyslog,logger
- 練習 19:文件系統:掛載,mount,/etc/fstab
- 練習 20:文件系統:修改和創建文件系統,tune2fs,mkfs
- 練習 21:文件系統:修改根目錄,chroot
- 練習 22:文件系統:移動數據,tar,dd
- 練習 23:文件系統:權限,chown,chmod,umask
- 練習 24:接口配置,ifconfig,netstat,iproute2,ss,route
- 練習 25:網絡:配置文件,/etc/network/interfaces
- 練習 26:網絡:封包過濾配置,iptables
- 練習 27:安全 Shell,ssh,sshd,scp
- 練習 28:性能:獲取性能情況,uptime,free,top
- 練習 29:內核:內核消息,dmesg
- 練習 30:打磨、洗練、重復:總復習
- 下一步做什么
- Debian 手動安裝