Linux 中 rc.local、init.d、rc.x、init 這幾個文件(夾)各有什麼作用?啟動執行的腳本應該均放在 rc.local 中嗎?

希望各位能講清楚通俗些,最好能結合linux啟動過程講哈,我對這個問題似懂非懂,謝了。


這個問題涉及到Linux初始化init系統,RHEL 5為SysVinit,RHEL 6為Upstart,RHEL 7為Systemd,為更好地解釋這個問題,以下選取RHEL 5.x進行說明。

如流程圖所示,RHEL的啟動過程按步驟大致可以分為:
POST加電自檢--&>BIOS(Boot Sequence)--&>載入對應引導上的MBR(bootloader) --&>主引導設置載入其BootLoader--&>Kernel初始化--&>initrd—&>/etc/init進程載入/etc/inittab從載入BootLoader(RHEL下為Grub)開始,會發生以下事情.
1. 藉由Grub的管理,讀取Kernel內核文件(/boot/vmlinuz),解壓至主內存,利用內核的功能,進行第二次硬體檢測(第一次發生在POST開機自檢時)
2. 載入Initial RAM Disk(/boot/initrd),使之在內存中解壓縮為根目錄,kernel藉此完成驅動程序的載入,,最終釋放虛擬文件系統,並掛載實際的根目錄文件系統.
3. 在核心載入完畢,進行完硬體偵測與驅動程序載入後,內核會啟動第一個進程/sbin/init, init進程將會讀取/etc/inittab,在/etc/inittab中,大致規定了以下動作:

  1. 取得 runlevel 亦即默認運行等級的相關等級.
  2. 使用 /etc/rc.d/rc.sysinit 進行系統初始化
  3. 根據runlevel調用相關啟動腳本,以啟動相應的系統服務
  4. 其他一些系統設置,最終完成系統啟動.

/sbin/init 最主要的功能就是準備軟體運行的環境,包括系統的主機名稱、網路配置、語系處理、文件系統格式及其他服務的啟動等,而所有的動作都根據在/etc/inittab中的配置.

/etc/rc.d, 裡面存放了rc.local, rc.sysinit, init.d, rcX.d (X包括0-6對應相對runlevel)

/etc/rc.d/init.d, 存放了各種系統服務的啟動關閉的管理腳本,/etc/init.d是他的一個目錄鏈接.

/etc/rc.d/rcX.d, 裡面存放了一些腳本,腳本名字以K開頭的,表示STOP動作,名字以S開頭,表示Start動作,名稱中的數字表示執行次序,數字越小表示越先執行.
/etc/rcX.d是他的目錄鏈接,但事實上rcX.d下文件本身就是指向/etc/rc.d/init.d下腳本的鏈接文件.

/etc/rc.d/rc.local, 有一個鏈接文件,路徑在/etc/rc.local,
系統根據runlevel啟動完rcX.d中的腳本之後,會調用rc.local腳本,如果你有一個腳本命令不論在3和5都想開機啟動,那麼就添加與此,免去rc3.d和rc5.d分別增加啟動腳本工作量.


啟動過程每個不同的Linux發行版有些許的不同,參照ArchLinux的啟動過程,簡單描述如下:
1. Boot Loader(如Grub) 載入Linux內核鏡像
2. Linux內核載入初始內存文件系統(intramfs),並執行/init進程,這是系統中的第一個進程。
3. 內核模塊初始化完畢後,真正的物理文件系統載入,/sbin/init進程替換之前啟動的/init進程。
4. init進程讀取/etc/inittab,開始執行各種初始化腳本
下面是ArchLinux的啟動腳本執行的過程(BSD-Style),和其他發行版有一定的區別
5. 首先執行的是/etc/rc.sysinit
6. 根據Run Level,執行/etc/rc.single(1或S)或者/etc/rc.multi(2-5),在這一步,就會執行/etc/rc.d下所有的腳本
7. 最後執行/etc/rc.local

ArchLinux的系統啟動腳本是很簡單,不像Redhat。不清楚其他的發行版啟動過程,但是/etc/inittab文件應該是一樣的功能,就是控制在不同的Run Level中如何進行系統腳本啟動。


Linux各發行版的啟動方式是有些許差異的,網上流傳最經典的就是紅帽系了。
我想對這個問題的陳述一點淺見。以下內容如有理解不當的地方,還請各位批評指正。

紅帽系的linux啟動過程如 @楊小浩 老師的圖形所示。和樓主問題最相關的是圖中最後一個過程,可以簡要的歸納為:

  1. 根據/etc/inittab啟動init進程
  2. init進程執行/etc/rc.d/rc.sysinit
  3. init進程完成run-level之間的各個服務啟動(在/etc/rc.d/rcN.d下有一堆軟連接l指向/etc/rc.d/init.d)
  4. init進程執行/etc/rc.d/rc.local(在/etc/rc.d/rcN.d下有一個軟連接S99local指向/etc/rc.d/rc.local)
  5. init進程完成tty

這裡init過程涉及到若干初始化的配置文件、腳本、目錄,這些初始化相關的配置文件、腳本、目錄看起來似乎並沒有太多層次感(注意:僅僅是看起來似乎是沒有層次感),這可能也是困擾樓主的地方。

老師教導我們分析問題,應該先抓住主要矛盾——這些繁雜的文件有一個主線,那就是

/etc/inittab

這個文件。inittab詳細規劃、控制了啟動的詳細過程。掌握了inittab,才能對這些繁雜的文件目錄樹有一個基本的了解。至於inittab的詳細語法、內容請自行man。簡要的說(不夠準確),linux的inittab過程可以歸結為三大步驟:

  • 系統初始化:rc.sysinit
  • 服務啟動:rc N 啟動rcN.d下的服務
  • 本地初始化:rc.local

如果樓主曾細心觀察過inittab源代碼,樓主應該會好奇第三個步驟rc.local是如何被inittab控制調用的,甚至也許會對第三個過程是否真正發生提出質疑。我們稍後會在後文再行討論這個問題。

考慮到這些配置文件、目錄、程序有各種亂七八糟的link,建議先拋開繁複的文件鏈接不管,得到如下的主幹層次結構(#字元後面註解了樓主提到個各類文件的作用):

/etc/inittab #初始化的主幹文件
/etc/rc.d #初始化的相關rc文件目錄,下面有五個文件夾

  • /etc/rc.d/rc.sysinit #系統初始化程序
  • /etc/rc.d/rc #相應啟動級別下的關鍵初始化程序,用以執行相應/etc/rc.d/rcN.d下的所有程序
  • /etc/rc.d/rcN.d/ #N取值範圍為[0,6],含有各類S和K開頭的軟連接文件,軟連接至rc.d/init.d/下各類服務和rc.local腳本
  • /etc/rc.d/init.d/ #含有各類服務程序
  • /etc/rc.d/rc.local #本地初始化程序

其中/etc/rc.d 目錄下這五個文件夾一定程度上代表了inittab的啟動內容,其中,rc.sysinit和rc這兩個程序最為關鍵。啟動過程首先是rc.sysinit,最後是rc.local,中間是通過rc N 程序調用etc/rc.d/rcN.d下的指向etc/rc.d/init.d下的程序軟連接。(暫未考慮tty)

到這裡,樓主的問題基本算解決了。但是且慢,rc.local是如何發生作用的?我們說inittab規划了初始化的詳細過程,但是inittab中為什麼沒有規劃rc.local調用的相關設定?


這個問題的關鍵在於上文提到的相關目錄層級中的相應rc級別下的關鍵初始化程序/etc/rc.d/rc,這個程序接收一個0-6範圍內的整數,執行rcN.d下的服務腳本(inittab的第二大步驟),而在rcN.d下有一個軟連接S99local指向了rc.local(inittab的第三大步驟)。因此嚴格來說,inittab的第三步驟實際發生在第二步驟內,這也是rc.local得以執行的關鍵。


至於Ubuntu,這個發行版的Linux並沒有inittab這個表。原因是他們認為上文這種依次執行的串列方式費時,於是採用了upstart的基於event的方式。類似的,Ubuntu也有相應的配置文件,具體的相關名字、目錄層級記得不太清楚了,由於手頭暫時沒有可用的Ubuntu機器,暫時不敢胡言亂語。


請樓主和各位批評、指正。


LZ提到的是關於Linux啟動這些腳本可以參考IBM上劉明工程師寫的文檔(https://www.ibm.com/developerworks/cn/linux/1407_liuming_init1/)

另:
rc是UNIX的SysVinit方式的啟動腳本,已經很古老了;在ubuntu等使用的的Upstart方式中得到了兼容(參考:淺析 Linux 初始化 init 系統,第 2 部分: UpStart)但如archlinux或是CentOS7採用了更激進更linux特色的systemd方式,(參考:淺析 Linux 初始化 init 系統,第 3 部分: Systemd)這種方式下根本沒有init.d或是rc.local。


下面是我的理解:init 文件名,指的是系統啟動的第一個腳本
init.d 目錄名,目錄內放的是各個服務的啟動腳本,比如sshd、httpd等
rcX.d 目錄名,後面的X代表著每個運行級別。目錄內有每個服務在init.d內啟動腳本的鏈接文件,根據鏈接文件的名字來的啟動狀態。K開頭表示不啟動服務,S打頭表示啟動服務
rc.local 鏈接文件,指到/etc/rc.d/rc.local。是系統初始化及服務均啟動完畢後,最後執行的一個腳本,一些簡單的腳本可以放到其中


ubuntu 使用upstart一種基於事件驅動的服務啟動機制
比如你有下面6個運行級別
0.halt
1.Single-User mode
2.Full Multi-User Mode (Ubuntu DEFAULT)
3.Full Multi-User Mode
4.Full Multi-User Mode
5.Full Multi-User Mode
6.Reboot
分別位於:
/etc/rc0.d/ = Run Level 0
/etc/rc1.d/ = Run Level 1
/etc/rc2.d/ = Run Level 2
/etc/rc3.d/ = Run Level 3
/etc/rc4.d/ = Run Level 4
/etc/rc5.d/ = Run Level 5
/etc/rc6.d/ = Run Level 6

當你系統啟動時,會執行rc2.d里的幾個腳本。

$ ls /etc/rc2.d/
README S20rsync S20thinkfan S70dns-clean S99ondemand
S20hddtemp S20speech-dispatcher S20virtualbox S70pppd-dns S99rc.local
S20kerneloops S20sysfsutils S50saned S99grub-common


有一個朋友在群里問,如何開機啟動isc dhcp 服務(樹莓派),我說修改cr.local文件,但是為什麼他們都說我是SB呢?

因為家裡沒有無線鍵盤,和有線鍵盤(本來是該用樹莓派的),我用的kali。然後沒有
裝isc dhcp 我用的ssh代替了,修改rc.local文件是可以實現ssh開機啟動的呀!

我在群里問一個很熱心的牛說了這句話,不明白意思,求指教啊。嘿嘿,然後他們為毛說我是SB呀?能回答仔細點么?大牛們


說一下Ubuntu 上的啟動方式,以及這些文件夾的作用
Ubuntu 採用了一個新的啟動方式 Upstart 代替基於System V的啟動方式。
init 程序啟動以後會查看 /etc/init/文件夾下的配置文件,此類以 .conf 結尾的文件類似於注意函數之類的東西,其中有以 rc 開頭的配置文件用來兼容以 System V 啟動方式,從這幾個文件可以向下摸,就能找到其它幾個文件夾的作用。
init.d是一些程序或者程序的鏈接,rcX.d是一些指向init.d下程序的有特殊命令規範的一些鏈接。程序 rc 要根據rcX.d 文件命名來啟動一部分程序。(這裡說的有點亂,其實就是System V的啟動方式)
而 /etc/init/下的配置文件應該一看就明白了!

breaker@breaker-linux:~$ ls /etc/init/rc*
/etc/init/rc.conf /etc/init/rcS.conf /etc/init/rc-sysinit.conf

breaker@breaker-linux:/etc/init$ cat -n rc.conf
1 # rc - System V runlevel compatibility
2 #
3 # This task runs the old System V-style rc script when changing between
4 # runlevels.
5
6 description "System V runlevel compatibility"
7 author "Scott James Remnant &"
8
9 emits deconfiguring-networking
10 emits unmounted-remote-filesystems
11
12 start on runlevel [0123456]
13 stop on runlevel [!$RUNLEVEL]
14
15 export RUNLEVEL
16 export PREVLEVEL
17
18 console output
19 env INIT_VERBOSE
20
21 task
22
23 exec /etc/init.d/rc $RUNLEVEL

breaker@breaker-linux:/etc/init$ cat -n rc-sysinit.conf
1 # rc-sysinit - System V initialisation compatibility
2 #
3 # This task runs the old System V-style system initialisation scripts,
4 # and enters the default runlevel when finished.
5
6 description "System V initialisation compatibility"
7 author "Scott James Remnant &"
8
9 start on (filesystem and static-network-up) or failsafe-boot
10 stop on runlevel
11
12 # Default runlevel, this may be overriden on the kernel command-line
13 # or by faking an old /etc/inittab entry
14 env DEFAULT_RUNLEVEL=2
15
16 emits runlevel
17
18 # There can be no previous runlevel here, but there might be old
19 # information in /var/run/utmp that we pick up, and we don"t want
20 # that.
21 #
22 # These override that
23 env RUNLEVEL=
24 env PREVLEVEL=
25
26 console output
27 env INIT_VERBOSE
28
29 task
30
31 script
32 # Check for default runlevel in /etc/inittab
33 if [ -r /etc/inittab ]
34 then
35 eval "$(sed -nre "s/^[^#][^:]*:([0-6sS]):initdefault:.*/DEFAULT_RUNLEVEL="1";/p" /etc/inittab || true)"
36 fi
37
38 # Check kernel command-line for typical arguments
39 for ARG in $(cat /proc/cmdline)
40 do
41 case "${ARG}" in
42 -b|emergency)
43 # Emergency shell
44 [ -n "${FROM_SINGLE_USER_MODE}" ] || sulogin
45 ;;
46 [0123456sS])
47 # Override runlevel
48 DEFAULT_RUNLEVEL="${ARG}"
49 ;;
50 -s|single)
51 # Single user mode
52 [ -n "${FROM_SINGLE_USER_MODE}" ] || DEFAULT_RUNLEVEL=S
53 ;;
54 esac
55 done
56
57 # Run the system initialisation scripts
58 [ -n "${FROM_SINGLE_USER_MODE}" ] || /etc/init.d/rcS
59
60 # Switch into the default runlevel
61 telinit "${DEFAULT_RUNLEVEL}"
62 end script


推薦閱讀:

有哪些命令行的軟體堪稱神器?
Windows系統的註冊表有哪些缺陷?
Linode 里為什麼 Ubuntu 最火呢?
ubuntu 網路連接後有沒有自動執行的腳本?
Linux 怎麼讀?

TAG:Linux | Linux系統管理 | Ubuntu | Linux軟體 | Linux開發 | shellscript |