在系統或應用運維過程中,經常會自定義一些腳本來管理服務或應用,爲了方便我們會把腳本放到 /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]='a b' 那麼這樣輸出的也是 a b 這是一個整體,而如果沒有""
,這輸出的是 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