chkconfig 指令碼原理和編寫說明
在系統或應用運維過程中,經常會自定義一些指令碼來管理服務或應用,為了方便我們會把指令碼放到/etc/init.d/
目錄下做成服務並使用 service 命令(centos 7 以前的發行版本)來管理。而要將服務新增到開機啟動,我們就要使用 chkconfig 命令,所以在編寫這類指令碼時,必須符合 chkconfig 要求。
chkconfig 原理
使用 man 來看一下:
chkconfig - updates and queries runlevel information for system service
chkconfig
命令主要用來更新(啟動或停止)和查詢系統服務的執行級資訊。
謹記:chkconfig
不是立即自動禁止或啟用一個服務,它只是簡單的改變了符號連線。
使用語法
chkconfig [--add][--del][--list][系統服務] 或 chkconfig [--level <等級代號>][系統服務][on/off/reset]
使用例子
# 列出所有的系統服務 chkconfig --list # 增加 named 服務 chkconfig --add named # 刪除 named 服務 chkconfig --del named # 設定 named 在執行級別為2、3、4、5的情況下都是on(開啟)的狀態 chkconfig --level named 2345 on
新增服務
-
服務指令碼必須存放在
/etc/ini.d/
目錄下,並有執行許可權; -
chkconfig --add <servicename>
在chkconfig工具服務列表中增加此服務,此時服務會被在/etc/rc.d/rcN.d
中賦予K(關機時執行)/S(開機時執行) 入口了; -
chkconfig --level 35 <servicename> on
,修改服務的預設啟動等級。
/etc 目錄下有一組 rc 開頭目錄,它們用來存放在各個執行級別下linux 自動啟動的服務:
/etc/rc0.d/ #執行模式 0 下需要啟動的服務 /etc/rc1.d/ #執行模式 1 下需要啟動的服務 /etc/rc2.d/ #執行模式 2 下需要啟動的服務 /etc/rc3.d/ #執行模式 3 下需要啟動的服務 /etc/rc4.d/ #執行模式 4 下需要啟動的服務 /etc/rc5.d/ #執行模式 5 下需要啟動的服務 /etc/rc6.d/ #執行模式 6 下需要啟動的服務
編寫 chkconfig 指令碼說明
#!/bin/bash # chkconfig: 35 99 05 # description: Test chkconfig # file: /etc/init.d/foo env > /tmp/ENVLOG
第二行中
35
:就是哪種 runlevel 下啟動,如果是-
代表預設的級別(2345)
99
:在開機啟動指令碼中的啟動順序(第99個啟動),S99foo (越小優先權越高),格式:S+數字+服務名
05
:在關機時第 5 個停止, K05foo (越小優先權越高),格式:K+數字+服務名
其中的 S:代表開機 Start,K:代表關機 Kill
99
和05
都是代表的順序,所以在編寫服務啟動指令碼時這行是必不可少的。chkconfig
和description
兩行也是必不可少的,否則chkconfig --add xxxx
服務時會報 "xxxx 服務不支援 chkconfig"。
chkconfig 指令碼例項
寫一個 lvs-dr 模式的 realserver 指令碼,程式碼如下:
#!/bin/bash # chkconfig: 35 12 90 # description: LVS DR mode, realserver config script # file: /etc/init.d/realserver VIPS=(172.16.14.252 172.16.14.253) . /etc/rc.d/init.d/functions case "$1" in start) # Start LVS-DR real server on this machine /sbin/ifconfig lo down /sbin/ifconfig lo up echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce /sbin/sysctl -p >/dev/null 2>&1 for VI in ${!VIPS[@]}; do /sbin/ifconfig lo:$VI ${VIPS[$VI]} netmask 255.255.255.255 broadcast ${VIPS[$VI]} /sbin/route add -host ${VIPS[$VI]} dev lo:$VI done echo "RealServer Start OK" ;; stop) # Stop LVS-DR real server loopback device(s) for VI in ${!VIPS[@]}; do /sbin/ifconfig lo:$VI down /sbin/route del ${VIPS[$VI]} >/dev/null 2>&1 done echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce echo "RealServer Stoped" ;; status) # Status of LVS-DR real server vips=$(echo "${VIPS[@]}" | tr ' ', '|') haslo=`ifconfig -a | grep -Ec "$vips"` hasroute=`netstat -rn | grep -Ec "$vips"` if [ "$haslo" -lt 1 -o "$hasroute" -lt 1 ];then echo "LVS-DR real server Stopped!" else echo "LVS-DR real server Running..." fi ;; *) # Invalid entry echo "$0: Usage: $0 {start|status|stop}" exit 1 ;; esac
複習陣列的語法
陣列的操作語法,如下列出常見的操作:
語法 | 描述 |
---|---|
${!array[*]} | 獲取陣列所有鍵 |
${!array[@]} | 獲取陣列所有鍵 |
${array[*]} | 獲取陣列所有值 |
${array[@]} | 獲取陣列所有值 |
${#array[*]} | 獲取陣列的長度 |
${#array[@]} | 獲取陣列的長度 |
A[*]
與A[@]
的區別:當兩者都沒有用""
(引號)括起來的時候兩者是一樣的,但是有了""
:
-
@
:最大限度的保持原意,比如A[1]='ab' 那麼這樣輸出的也是 ab 這是一個整體,而如果沒有""
,這輸出的是 a b 這是兩個元素! -
*
:所有的元素都變成一個字串了,也就是一個整體。
示例:
$ for i in "${a[@]}";do echo $i+'aa';done 1 2 3+aa 4 5 6+aa 7 8 9+aa $ for i in "${a[*]}";do echo $i+'aa';done 1 2 3 4 5 6 7 8 9+aaa