linux下設置開機啓動項

服務(腳本)開機自啓的幾種方式

工作中正好要將某個腳本開機自啓,百度了一下大概有幾種方法:

  1. 將腳本放到 /etc/init.d/ 目錄下,再在 /etc/rcN.d (N 表示 0~6 這7個數字,分別代表 linux 的七個運行級別)目錄下創建腳本的軟連接
  2. 將腳本放到 /etc/inid.d/ 目錄下, 執行 chkconfig --add 腳本
  3. 編輯 /etc/rc.d/rc.local ,在 exit 0 之前添加執行相應腳本的語句
  4. crontab -e , 在定時任務中添加 @reboot 腳本名(全路徑)

具體這幾種方式有什麼區別,有沒有需要注意的地方?這兩天查了些資料,現在做個總結!要比較這幾種方式的優劣,還得從 linux 的開機流程說起
本文中我的系統版本是: CentOS release 6.10 (Final)

linux 開機流程

linux 的開機流程,大概如下

  1. 加載 BIOS 的硬件信息,並進行自我檢測,並依據設定取得第一個可開機的裝置(通常就是硬盤)
  2. 讀取並執行裝置內 MBR 的 boot loader (grub 等引導程序)
  3. 依據 boot loader 的設定加載核心 kernel, kernel 會開始偵測硬件並加載驅動程序
  4. 在硬件驅動成功後, 核心會主動呼叫 init 程序,而 init 會 根據設置的 run-level 信息(/etc/inittab 文件中定義了默認的運行級別)
  5. init 執行 /etc/rc.d/rc.sysinit 文檔來準備軟件執行的作業環境(例如網絡,語系,時區等)
  6. 執行 /etc/rc.d/rc $RUNLEVEL # $RUNLEVEL爲缺省的運行模式 根據 run-level執行對應目錄rcN.d下的服務(N 表示運行級別,例如rc3.d目錄下的服務就是全用戶文本模式下要開啓的服務)
  7. /etc/rc.d/rc.local #相應級別服務啓動之後、在執行該文件(其實也可以把需要執行的命令寫到該文件中)
  8. 執行終端仿真程序 mingetty 來啓動 login 程序,等待用戶登陸

前 3 步,主要是 linux 的核心加載,硬件檢測之類的,偏硬件方面些。在覈心加載完之後, linux 開始執行它的第一個程序 /sbin/init 了。 init 程序最主要的作用就是準備軟件執行的環境,包括系統主機名,網絡設定,語系設定,文件系統格式以及開機後的服務的啓動等。 而所有的活動都會通過 init 的配置文件,也即 /etc/inittab 文件來 規劃,而且 /etc/inittab 內還有一個很重要的設定:那就是確定系統的運行級別。

什麼是運行級別呢? 說白了,linux是多用戶的系統,它就是通過 run-level 來規定系使用不同的服務來啓動,讓linux的環境不同。具體分爲 7 個級別

  • 0 - halt (直接關機)
  • 1 - Single user mode 單人維護模式
  • 2 - Multiuser -without NFS 類似於下面的level 3 ,但是沒有NFS服務(也就是沒有網絡)
  • 3 - full multiuser mode 含義完整功能的的純文本模式
  • 4 系統保留功能
  • 5 -X11 圖形系統
  • 6 reboot 重啓

由於0,4,6 不是關機就是重啓或者不起作用,當然不能把默認的運行級別設置爲這幾樣,否則系統會關機或者不斷重啓,那麼系統到底是以什麼級別來運行的呢,那就要看 /etc/inittab

/etc/inittab
在這裏插入圖片描述

看最後一行,可以看到,現在默認的運行級別的3 ,也就是多用戶文本界面。從文件說明裏可以看到,這個文件被拆分到/etc/init/rcS.conf, /etc/init/rc.conf , /etc/init/control-alt-delete.conf , /etc/init/tty.conf 等多個文件,負責不同的功能了。 獲取到系統的運行級別之後, /etc/init/rcS.conf 就開始系統初始化工作,這個是非常重要的部分。那麼它是如何進行初始化的呢,我們打開 /etc/init/rcS.conf看看

/etc/rcS.conf
在這裏插入圖片描述
咦? 原來它是調用 /etc/rc.d/rc.sysinit 來進行初始化的啊。

/etc/rc.d/rc.sysinit 程序做的是系統在任何運行級別下都需要做的事情,而且跟許多系統配置文件密切相關。如果想要詳細瞭解,可以直接查看文檔瞭解(可能需要一些shell 腳本知識)

回到系統開機流程,那麼我們要在系統開機時執行我們自己的服務或者說腳本(這兩者沒有嚴格區分,你也可以把你自己的腳本註冊爲服務),我們可以在第6, 7 步做文章。

將腳本放到/etc/rc.d/init.d/目錄下,並在 rcN.d 目錄下創建軟鏈接

第六步是根據運行級別,執行/etc/rc.d/rcN.d(N 表示運行級別,0~6)目錄下的服務。
具體是怎麼執行的呢,其實是運行的/etc/rc.d/rc $RUNLEVEL , $RUNLEVEL是運行級別,打開/etc/rc.d/rc 文件,我們來看一看,裏面這麼一段
在這裏插入圖片描述
可以看到,它會遍歷 /etc/rcN.d/ 目錄下以S開頭的文件,並執行 exec $i start 命令。
這樣就很明朗了。

那麼我如果想要在3,5運行級別下開機執行我的程序,那麼只要把我們的程序放到這個rc3.d, rc5.d 目錄下不就OK了嗎。就這麼辦!那麼我們來看看rcN.d目錄下都是些什麼

/etc/rc.d 目錄
在這裏插入圖片描述
這裏rc0~6.d 分別代表各運行級別下需要執行的服務。

我們來看看rc3.d 目錄下到底是些什麼

/etc/rc.d/rc3.d 目錄
在這裏插入圖片描述

這裏面都是些軟鏈接,並且都指向 /etc/rc.d/init.d/ 目錄下的服務腳本,而且這裏的軟鏈接都是S或者K開頭,後接兩位數字,然後是服務文件名。具體含義是:
S 表示啓動(Start), K 表示關閉(Kill),後接的兩位數字表示 啓動的順序,數字越大,順序越靠後,優先級越低。例如 S99local 指向 /etc/rc.d/rc.local ,表示這個腳本也是開機啓動的,並且最後執行,數字99在兩位數裏已經是最後一個了。這個也是linux 系統預留給我們做一些啓動操作的腳本,可以將要執行的命令放到該文件中。
那麼要開機啓動,具體怎麼做呢:

  1. 將我們要執行的程序放到/etc/rc.d/init.d 目錄下
  2. 在對應的rcN.d 目錄下創建程序的軟鏈接,文件格式爲SxxYY (xx爲兩位數字,YY爲程序名)

舉例說明:我寫了一個測試腳本test.sh

test.sh

#/bin/bash
# chkconfig: 3 90 30
# description: test is just a test
echo "/etc/rc.d/init.d/test 開機自啓" >> /root/apps/1.log

輸出並追加到/root/apps/1.log文件中
在rc3.d 目錄下創建軟鏈接指向剛纔的腳本(我機子的默認運行級別是3,可以根據運行級別調整軟鏈接存放的位置)

cd rc3.d
ln -s ../init.d/test.sh S90test.sh

重啓,我們來看下 /root/apps/1.log 文件
在這裏插入圖片描述
說明我們的開機自啓是有效的。
而且另一個有趣的事情發生了。運行 chkconfig 命令,我發現多了一個test.sh的服務
在這裏插入圖片描述

關於 chkconfig 我們後面再講,這裏先備註一下。

將執行腳本的命令追加到 /etc/rc.d/rc.local 文件中

請注意到剛纔在看rc3 目錄下有哪些文件時,最後一行有一個軟鏈接指向了rc.local文件
在這裏插入圖片描述
而且不僅僅是rc3.d 目錄下有,rc2.d ,rc3.d 目錄下都有,而且優先級最後,也就是說在執行完其餘的服務之後,最後會執行 /etc/rc.d/rc.local 文件,那麼只要把執行我們腳本的命令追加到 rc.local 文件中,也能達到開機自啓的目的。
在這裏插入圖片描述
在最後一行執行我的測試腳本 test.sh 。
刪除/root/apps/1.log 文件,然後關機重啓。再次打開 /root/apps/1.log
在這裏插入圖片描述
發現輸出了兩行,因爲我們開機執行了這個腳本兩次,所以在rcN.d 中創建軟鏈接的方式和在rc.local中添加執行命令的方式,只要取一個就好,我這個測試腳本是兩個都設置了,所以執行了兩次。

使用chkconfig 命令將腳本註冊爲系統服務,並開機自啓

在第一種添加自啓動方式中,我們先將test.sh copy到 /etc/rc.d/init.d 目錄下,然後在
/etc/rc.d/rc3.d 目錄下創建軟鏈接文件S90test.sh , 使用 chkconfig命令的時候,我們發現列出的系統服務中多了一個 test.sh 出來
在這裏插入圖片描述
其實 chkconfig 命令的原理就是跟在 rcN.d 目錄下創建軟鏈接一樣,它把創建文件的工作通過命令的方式來執行。這裏需要注意一點,如果需要將某個腳本,程序使用chkconfig 命令添加到系統服務中去,那麼在腳本的開頭部分需要加上

#/bin/bash
# chkconfig: 2345 90 30

這樣的一句註釋,否則執行 chkconfig 命令會報錯。 這裏2345 表示在2、3、4、5這4個運行級別,如果只想在3這個級別上啓動,可以只寫3, 後面的90是啓動時候的優先級,兩位數,數字越大級別越低, 再後面的 30 是關閉的優先級,兩位數,同樣數字越大級別餘地,越晚關閉。
然後把腳本文件test.sh放到 /etc/rc.d/init.d 目錄下。
執行 chkconfig --add test.sh, chkconfig 命令會在當前的運行級別對應的rcN.d 目錄中添加一個軟鏈接 S90test.sh ,如果需要在多個運行級別中添加, 執行chkconfig --level 2345 --add test.sh命令。

chkconfig 命令原理: 添加系統服務時,在對應的rcN.d 目錄裏創建S開頭的軟鏈接,刪除系統服務時,在其它的rcN.d 某種創建K開頭的軟鏈接。

使用crontab -e命令,然後在文件末尾添加 @reboot 腳本全路徑名

這個其實不是linux 內核提供的功能,而是 cron 這個系統服務提供的功能。有些linux 版本默認提供了cron 這個定時任務的系統服務並作爲守護進程默認開啓,那麼就可以使用crontab 來配置開機啓動。
這個方法起作用的前提是安裝了 cronie 這個軟件,並且作爲守護進程開啓了。

chkconfig 

在這裏插入圖片描述
crond 服務作爲系統服務並且默認開啓。

crontab -e  然後輸入
@reboot /etc/rc.d/init.d/test.sh  # 絕對路徑
:wq

保存之後重啓,也可以起到開機自啓的功能。

注意事項,自啓程序不能依賴 /etc/profile 中的環境變量

從剛纔開機流程看,最後一步是通過 執行終端仿真程序 mingetty 來啓動 login 程序,等待用戶登陸。也就是說這個時候還沒有登陸,我們所設置的開機自啓的程序是在還沒有登陸的時候執行的,也就是說一些需要登陸之後設置的環境變量這時候還沒有設置,如果需要設置環境變量,程序中要自行設置,不能依賴 /etc/profile中設置的環境變量。

用戶登錄時,bash首先自動執行系統管理員建立的全局登錄script :/ect/profile。然後bash在用戶起始目錄下按順序查找三個特殊文件中的一個:.bash_profile、.bash_login、 .profile
如果需要設置用戶登陸時啓動的程序,可以在 .bash_profile中設置(系統可以重複登陸)

退出登錄時,bash自動執行個人的退出登錄腳本/.bash_logout。例如,在/.bash_logout中加入命令“tar -cvzf c.source.tgz *.c”,則在每次退出登錄時自動執行 “tar” 命令備份 *.c 文件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章