getpots是Shell命令行參數解析工具,旨在從Shell Script的命令行當中解析參數。getopts被Shell程序用來分析位置參數,option包含須要被識別的選項字符,若是這裏的字符後面跟着一個冒號,代表該字符選項須要一個參數,其參數須要以空格分隔。冒號和問號不能被用做選項字符。getopts每次被調用時,它會將下一個選項字符放置到變量中,OPTARG則能夠拿到參數值;若是option前面加冒號,則表明忽略錯誤;java
命令格式:web
getopts optstring name [arg...]
命令描述:
optstring列出了對應的Shell Script能夠識別的全部參數。好比:若是 Shell Script能夠識別-a,-f以及-s參數,則optstring就是afs;若是對應的參數後面還跟隨一個值,則在相應的optstring後面加冒號。好比,a:fs 表示a參數後面會有一個值出現,-a value的形式。另外,getopts執行匹配到a的時候,會把value存放在一個叫OPTARG的Shell Variable當中。若是 optstring是以冒號開頭的,命令行當中出現了optstring當中沒有的參數將不會提示錯誤信息。shell
name表示的是參數的名稱,每次執行getopts,會從命令行當中獲取下一個參數,而後存放到name當中。若是獲取到的參數不在optstring當中列出,則name的值被設置爲?。命令行當中的全部參數都有一個index,第一個參數從1開始,依次類推。 另外有一個名爲OPTIND的Shell Variable存放下一個要處理的參數的index。bash
示例說明:
1)在shell腳本中,對於簡單的參數,經常會使用$1,$2,...,$n來處理便可,具體以下:服務器
[root@bobo tmp]# cat test.sh #!/bin/bash SYSCODE=$1 APP_NAME=$2 MODE_NAME=$3 echo "${SYSCODE}下的${APP_NAME}分佈在${MODE_NAME}裏面" [root@bobo tmp]# sh test.sh caiwu reops kebank_uut caiwu下的reops分佈在kebank_uut裏面
上面的例子中參數少還能夠,可是若是腳本中使用的參數很是多的狀況下,那使用上面這種方式就很是不合適,這樣就沒法清楚地記得每一個位置對應的是什麼參數!這個時候咱們就可使用bash內置的getopts工具了,用於解析shell腳本中的參數!下面就來看幾個例子:app
2)getopts 示例一jvm
[root@bobo tmp]# cat test.sh #!/bin/bash func() { echo "Usage:" echo "test.sh [-j S_DIR] [-m D_DIR]" echo "Description:" echo "S_DIR,the path of source." echo "D_DIR,the path of destination." exit -1 } upload="false" while getopts 'h:j:m:u' OPT; do case $OPT in j) S_DIR="$OPTARG";; m) D_DIR="$OPTARG";; u) upload="true";; h) func;; ?) func;; esac done echo $S_DIR echo $D_DIR echo $upload
執行腳本工具
[root@bobo tmp]# sh test.sh -j /data/usw/web -m /opt/data/web /data/usw/web /opt/data/web false [root@bobo tmp]# sh test.sh -j /data/usw/web -m /opt/data/web -u /data/usw/web /opt/data/web true [root@bobo tmp]# sh test.sh -j /data/usw/web /data/usw/web false [root@bobo tmp]# sh test.sh -m /opt/data/web /opt/data/web false [root@bobo tmp]# sh test.sh -h test.sh: option requires an argument -- h Usage: test.sh [-j S_DIR] [-m D_DIR] Description: S_DIR,the path of source. D_DIR,the path of destination. [root@bobo tmp]# sh test.sh j false [root@bobo tmp]# sh test.sh j m false
getopts後面跟的字符串就是參數列表,每一個字母表明一個選項,若是字母后面跟一個:,則就表示這個選項還會有一個值,好比上面例子中對應的-j /data/usw/web 和-m /opt/data/web 。而getopts字符串中沒有跟隨:的字母就是開關型選項,不須要指定值,等同於true/false,只要帶上了這個參數就是true。ui
getopts識別出各個選項以後,就能夠配合case進行操做。操做中,有兩個"常量",一個是OPTARG,用來獲取當前選項的值;另一個就是OPTIND,表示當前選項在參數列表中的位移。case的最後一項是?,用來識別非法的選項,進行相應的操做,咱們的腳本中輸出了幫助信息。編碼
3)getopts示例二:當選項參數識別完成之後,就能識別剩餘的參數了,咱們可使用shift進行位移,抹去選項參數。
[root@bobo tmp]# cat test.sh #!/bin/bash func() { echo "func:" echo "test.sh [-j S_DIR] [-m D_DIR]" echo "Description:" echo "S_DIR, the path of source." echo "D_DIR, the path of destination." exit -1 } upload="false" echo $OPTIND while getopts 'j:m:u' OPT; do case $OPT in j) S_DIR="$OPTARG";; m) D_DIR="$OPTARG";; u) upload="true";; ?) func;; esac done echo $OPTIND shift $(($OPTIND - 1)) echo $1
執行腳本:
[root@bobo tmp]# sh test.sh -j /data/usw/web beijing 1 #執行的是第一個"echo $OPTIND" 3 #執行的是第二個"echo $OPTIND" beijing #此時$1是"beijing" [root@bobo tmp]# sh test.sh -m /opt/data/web beijing 1 #執行的是第一個"echo $OPTIND" 3 #執行的是第二個"echo $OPTIND" beijing [root@bobo tmp]# sh test.sh -j /data/usw/web -m /opt/data/web beijing 1 #執行的是第一個"echo $OPTIND" 5 #執行的是第二個"echo $OPTIND" beijing 參數位置: 1 2 3 4 5 6 [root@bobo tmp]# sh test.sh -j /data/usw/web -m /opt/data/web -u beijing 6 beijing
在上面的腳本中,咱們位移的長度等於case循環結束後的OPTIND - 1,OPTIND的初始值爲1。當選項參數處理結束後,其指向剩餘參數的第一個。getopts在處理參數時,處理帶值的選項參數,OPTIND加2;處理開關型變量時,OPTIND則加1。
如上執行的腳本:1)第一個腳本執行,-j的參數位置爲1,因爲-j後面帶有參數,即處理帶值選項參數,因此其OPTIND爲1+2=3;2)第二個腳本執行,-m參數位置爲1,因爲其後帶有參數,因此其OPTIND也爲1+2=3;3)第三個腳本執行,-m的參數位置 (觀察最後一個參數的位置) 爲3,因爲其後面帶有參數,因此其OPTIND爲3+2=5;4)第四個腳本執行,-u參數位置爲5,因爲其後面不帶參數,即爲處理開關型變量,因此其OPTIND爲5+1=6。
shift參數的使用
不少腳本執行的時候咱們並不知道後面參數的個數,但可使用$*來獲取全部參數。但在程序處理的過程當中有時須要逐個的將$一、$二、$3……$n進行處理。shift是shell中的內部命令,用於處理參數位置。每次調用shift時,它將全部位置上的參數減一。 $2變成了$1, $3變成了$2, $4變成了$3。shift命令的做用就是在執行完$1後,將$2變爲$1,$3變爲$2,依次類推。
示例一: [root@bobo tmp]# cat test.sh #!/bin/bash until [ $# -eq 0 ] do echo "第一個參數爲: $1 參數個數爲: $#" shift done [root@bobo tmp]# sh test.sh 10 11 12 13 14 15 第一個參數爲: 10 參數個數爲: 6 第一個參數爲: 11 參數個數爲: 5 第一個參數爲: 12 參數個數爲: 4 第一個參數爲: 13 參數個數爲: 3 第一個參數爲: 14 參數個數爲: 2 第一個參數爲: 15 參數個數爲: 1 示例二: [root@bobo tmp]# cat test.sh #!/bin/bash until [ -z "$1" ] # Until all parameters used up do echo "$@ " shift done [root@bobo tmp]# sh test.sh 10 11 12 13 14 15 10 11 12 13 14 15 11 12 13 14 15 12 13 14 15 13 14 15 14 15 15
4)getopts示例三
[root@bobo tmp]# cat test.sh #!/bin/bash echo $* while getopts ":a:bc:" opt do case $opt in a) echo $OPTARG echo $OPTIND ;; b) echo "b $OPTIND" ;; c) echo "c $OPTIND" ;; ?) echo "error" exit 1 esac done echo $OPTIND shift $(( $OPTIND-1 )) echo $0 echo $* [root@bobo tmp]# sh test.sh -a beijing -b -c shanghai -a beijing -b -c shanghai #執行的是第一個"echo $*",即打印"傳遞給腳本的全部參數的列表" beijing #執行的是"echo $OPTARG", OPTARG表示存儲相應選項的參數,這裏指-a的參數"beijing" 3 #-a參數位置爲1,是處理帶值選項參數,即-a參數的OPTIND爲1+2=3 b 4 #-b參數位置爲3,是處理開關型變量(即後面沒有跟參數),即-b參數的OPTIND爲3+1=4 c 6 #-c參數位置爲4,是處理帶值選項參數,即-a參數的OPTIND爲4+2=3 6 #執行的是"echo $OPTIND",此時打印的是腳本執行的最後一個參數(即-c)的OPTIND的index索引值。 test.sh #執行的是"echo $0",即打印腳本名稱。$0是腳本自己的名字; #執行的是最後一個"echo $*",即打印"傳遞給腳本的全部參數的列表"。因爲前面執行了shift $(( $OPTIND-1 )),即每執行一步,位置參數減1,因此到最後$*就爲零了。 [root@bobo tmp]#
5)getopts示例四
[root@bobo tmp]# cat test.sh #!/bin/bash # getopts-test.sh while getopts :d:s ha do case "$ha" in d) echo "d option value is $OPTARG" echo "d option index is $(($OPTIND-1))" ;; s) echo "s option..." echo "s option index is $(($OPTIND-1))" ;; [?]) print "Usage: $0 [-s] [-d value] file ..." exit 1 ;; esac done 執行腳本: [root@bobo tmp]# sh test.sh -d 100 -s d option value is 100 #打印的是對應選項的參數,即-d的參數值 d option index is 2 #-d參數位置爲1,是處理帶值選項參數,即-d參數的OPTIND爲1+2=3。因此$(($OPTIND-1))爲2 s option... s option index is 3 #-s參數位置爲3,是處理帶值選項參數,即-s參數的OPTIND爲3+1=4。因此$(($OPTIND-1))爲2 ================================================================================== [root@bobo tmp]# cat test.sh #!/bin/bash while getopts :ab:c: OPTION;do #ab參數前面的:表示忽略錯誤 case $OPTION in a)echo "get option a" ;; b)echo "get option b and parameter is $OPTARG" ;; c)echo "get option c and parameter is $OPTARG" ;; ?)echo "get a non option $OPTARG and OPTION is $OPTION" ;; esac done [root@bobo tmp]# sh test.sh -a haha get option a [root@bobo tmp]# sh test.sh -b hehe get option b and parameter is hehe [root@bobo tmp]# sh test.sh -a haha -b hehe #因爲getopts解析時ab參數在一塊兒,-a和-b都跟參數時,-a在前面執行後,-b參數就不會執行了。 get option a [root@bobo tmp]# sh test.sh -b haha -a hehe #將-b參數放在前面執行,-a參數放在後面執行,兩個參數就均可以執行了。 get option b and parameter is haha get option a [root@bobo tmp]# sh test.sh -ab hehe get option a get option b and parameter is hehe [root@bobo tmp]# sh test.sh -ab hehe -c heihei get option a get option b and parameter is hehe get option c and parameter is heihei [root@bobo tmp]# sh test.sh -ab hehe -c heihei -u liu get option a get option b and parameter is hehe get option c and parameter is heihei get a non option u and OPTION is ? ================================================================================ 稍微修改下腳本,將abc參數放在一塊兒 [root@bobo tmp]# cat test.sh #!/bin/bash while getopts :abc: OPTION;do case $OPTION in a)echo "get option a" ;; b)echo "get option b and parameter is $OPTARG" ;; c)echo "get option c and parameter is $OPTARG" ;; ?)echo "get a non option $OPTARG and OPTION is $OPTION" ;; esac done [root@bobo tmp]# sh test.sh -a haha get option a [root@bobo tmp]# sh test.sh -a haha -b hehe get option a [root@bobo tmp]# sh test.sh -a haha -c heihei get option a [root@bobo tmp]# sh test.sh -a haha -b hehe -c heihei get option a [root@bobo tmp]# sh test.sh -a haha -c hehe -b heihei get option a [root@bobo tmp]# sh test.sh -b hehe get option b and parameter is [root@bobo tmp]# sh test.sh -b haha -a hehe get option b and parameter is [root@bobo tmp]# sh test.sh -b haha -c hehe get option b and parameter is [root@bobo tmp]# sh test.sh -b haha -a hehe -c heihei get option b and parameter is [root@bobo tmp]# sh test.sh -b haha -c hehe -a heihei get option b and parameter is [root@bobo tmp]# sh test.sh -c haha get option c and parameter is haha [root@bobo tmp]# sh test.sh -c haha -a hehe get option c and parameter is haha get option a [root@bobo tmp]# sh test.sh -c haha -b heihei get option c and parameter is haha get option b and parameter is [root@bobo tmp]# sh test.sh -c haha -a hehe -b heihei get option c and parameter is haha get option a [root@bobo tmp]# sh test.sh -c haha -b hehe -c heihei get option c and parameter is haha get option b and parameter is [root@bobo tmp]# sh test.sh -abc hehe get option a get option b and parameter is get option c and parameter is hehe
6)再來看一個zookeeper集羣環境安裝的腳本(用到了getopts),生產環境中可使用該腳本。
[root@bobo zookeeper]# cat install_zookeeper.sh #!/bin/bash source /etc/profile java -version if [ "$?" -ne 0 ]; then echo "JDK未安裝,請先安裝JDK" exit 1 fi while getopts "a:b:n:l:c:f:m:h" opts do case $opts in a) #APP_NAME:項目編碼 APP_NAME=$OPTARG ;; b) #MODULE_NAME:模塊名稱 MODULE_NAME=$OPTARG ;; n) #ZK_SRVNUM:ZOOKEEPER數量 ZK_SRVNUM=$OPTARG ;; l) #ZK_IPLIST:ZOOKEEPER服務器IP地址列表 ZK_IPLIST=$OPTARG ;; c) #ZKCLIENT_PORT:客戶端訪問 zookeeper 的端口號 ZKCLIENT_PORT=$OPTARG ;; f) #ZKLEADER_PORT:ZOOKEEPER的F和L通訊端口號 ZKLEADER_PORT=$OPTARG ;; m) #ZKCOM_PORT:ZOOKEEPER選舉端口號 ZKCOM_PORT=$OPTARG ;; h) echo -e "OPTIONS:\n-a:項目編碼(必選)\n-b:模塊名稱(可選,默認爲空)\n-n:ZooKeeper服務器數量(可選,默認爲3)" echo -e "-l:ZooKeeper服務器IP地址列表(必選,IP地址以英文逗號分隔)" echo -e "-c:Client-Port(可選,默認爲2181,多個端口以英文逗號分隔,且與IP地址一一對應)" echo -e "-f:ZooKeeper的F和L通訊端口號(可選,默認爲2888,多個端口以英文逗號分隔,且與IP地址一一對應)" echo -e "-m:ZooKeeper選舉端口號(可選,默認爲3888,多個端口以英文逗號分隔,且與IP地址一一對應)" exit 1 ;; ?) echo "missing options,pls check!" exit 1 ;; esac done #可選參數賦值 ZK_SRVNUM=${ZK_SRVNUM:-3} ZKCLIENT_PORT=${ZKCLIENT_PORT:-2181} ZKLEADER_PORT=${ZKLEADER_PORT:-2888} ZKCOM_PORT=${ZKCOM_PORT:-3888} #定義公共變量 #zookeep安裝包存放位置 ZKSAVDIR="/software/linxin/zookeeper" #zookeeper安裝包名(不帶擴展名) ZKNAME="zookeeper-3.4.8" #必選參數存在性及參數合法性判斷 #if [ -z ${APP_NAME} ]||[ -z ${MODULE_NAME} ]||[ -z ${ZK_IPLIST} ];then if [ -z ${APP_NAME} ]||[ -z ${ZK_IPLIST} ];then echo "Missing options,exit" exit 1 elif [ ${ZK_SRVNUM} -ne 1 ]&&[ ${ZK_SRVNUM} -ne 3 ]&&[ ${ZK_SRVNUM} -ne 5 ];then echo "Wrong server num,exit" exit 1 fi IPLIST_NUM=`echo ${ZK_IPLIST}|awk -F"," '{print NF}'` if [ ${ZK_SRVNUM} -ne ${IPLIST_NUM} ];then echo "IP list and server num do not match,exit" exit 1 fi APP_NAME=`echo ${APP_NAME} | tr '[A-Z]' '[a-z]'` #多個端口時判斷端口數與IP地址數量是否一致 CPORT_NUM=`echo ${ZKCLIENT_PORT}|awk -F"," '{print NF}'` LPORT_NUM=`echo ${ZKLEADER_PORT}|awk -F"," '{print NF}'` EPORT_NUM=`echo ${ZKCOM_PORT}|awk -F"," '{print NF}'` if [ ${CPORT_NUM} -gt 1 ];then if [ ${IPLIST_NUM} -ne ${CPORT_NUM} ]||[ ${IPLIST_NUM} -ne ${LPORT_NUM} ]||[ ${IPLIST_NUM} -ne ${EPORT_NUM} ];then echo "IP list and Port list number do not match,exit" exit 1 fi #獲取IP地址和端口對應關係 rm -f /home/workapp/zkinfo.cfg for ((i=1;i<=${ZK_SRVNUM};i++)); do eval IP_$i='`echo ${ZK_IPLIST}|awk -F, "{ print $"$i" }"`' eval PORT_$i='`echo ${ZKCLIENT_PORT}|awk -F, "{ print $"$i" }"`' eval LPORT_$i='`echo ${ZKLEADER_PORT}|awk -F, "{ print $"$i" }"`' eval EPORT_$i='`echo ${ZKCOM_PORT}|awk -F, "{ print $"$i" }"`' # eval echo "server.${i}=\$IP_$i:${ZKLEADER_PORT}:${ZKCOM_PORT}">>${ZKHOME}/conf/zoo.cfg # eval IPTMP=\$IP_$i eval PORTTMP=\$PORT_$i #zookeeper HOME路徑 [ -z ${MODULE_NAME} ]&&eval ZKHOME="/opt/${APP_NAME}/zookeeper_\$PORT_$i"||eval ZKHOME="/opt/${APP_NAME}/zookeeper_${MODULE_NAME}_\$PORT_$i" #zookeeper日誌存儲路徑 [ -z ${MODULE_NAME} ]&&eval DATA_LOGDIR="/var/log/${APP_NAME}/zookeeper_\$PORT_$i"||eval DATA_LOGDIR="/var/log/${APP_NAME}/zookeeper_${MODULE_NAME}_\$PORT_$i" #zookeeper數據存儲路徑 DATA_DIR="${ZKHOME}/data" #生成參數列表 eval echo "$i,\$IP_$i,\$PORT_$i,\$LPORT_$i,\$EPORT_$i,${ZKHOME},${DATA_LOGDIR},${DATA_DIR}">>/home/workapp/zkinfo.cfg done cat /home/workapp/zkinfo.cfg else #zookeeper HOME路徑 [ -z ${MODULE_NAME} ]&&ZKHOME="/opt/${APP_NAME}/zookeeper"||ZKHOME="/opt/${APP_NAME}/zookeeper_${MODULE_NAME}" echo "ZKHOME is ${ZKHOME}" #zookeeper日誌存儲路徑 [ -z ${MODULE_NAME} ]&&DATA_LOGDIR="/var/log/${APP_NAME}/zookeeper"||DATA_LOGDIR="/var/log/${APP_NAME}/zookeeper_${MODULE_NAME}" echo "ZK log dir is ${DATA_LOGDIR}" #zookeeper數據存儲路徑 DATA_DIR="${ZKHOME}/data" echo "ZK data dir is ${DATA_DIR}" fi #安裝日誌 INSTALL_LOG="/home/workapp/zookeeperinstall.log" #打印變量值 echo "APP_NAME is ${APP_NAME}"|tee -a ${INSTALL_LOG} echo "MODULE_NAME is ${MODULE_NAME}"|tee -a ${INSTALL_LOG} echo "ZK_Server_num is ${ZK_SRVNUM}"|tee -a ${INSTALL_LOG} echo "ZK_Server IP is ${ZK_IPLIST}"|tee -a ${INSTALL_LOG} echo "ZK_Client Port is ${ZKCLIENT_PORT}"|tee -a ${INSTALL_LOG} echo "ZK_Leader Port is $ZKLEADER_PORT"|tee -a ${INSTALL_LOG} echo "ZK_COM Port is ${ZKCOM_PORT}"|tee -a ${INSTALL_LOG} #獲取本機IP地址 HOST_IP=`ip a|grep global|awk '{print $2}'|awk -F"/" '{print $1}'` echo "Local IP is ${HOST_IP}"|tee -a ${INSTALL_LOG} #安裝包MD5校驗 md5Now=`md5sum ${ZKSAVDIR}/${ZKNAME}.tar.gz|awk '{print $1}'` md5Save=`cat ${ZKSAVDIR}/${ZKNAME}.tar.gz.md5` if [ "${md5Now}" != "${md5Save}" ];then echo "MD5 check Failed!"|tee -a ${INSTALL_LOG} echo "the md5 now is ${md5Now}"|tee -a ${INSTALL_LOG} echo "the md5 saved is ${md5Save}"|tee -a ${INSTALL_LOG} exit 1 else echo "MD5 check success!"|tee -a ${INSTALL_LOG} fi #安裝zookeeper function Install_zk { echo "=================`date '+%Y%m%d %H:%M:%S'`Start Install ZooKeeper....==============="|tee -a ${INSTALL_LOG} #解壓縮安裝包至項目編碼安裝路徑 if [ ! -e /opt/${APP_NAME}/ ]; then mkdir -p /opt/${APP_NAME} fi tar -xzf ${ZKSAVDIR}/${ZKNAME}.tar.gz -C /opt/${APP_NAME}/ mv /opt/${APP_NAME}/${ZKNAME} ${ZKHOME} mkdir -p ${DATA_DIR} mkdir -p ${DATA_LOGDIR} cp ${ZKHOME}/conf/zoo_sample.cfg ${ZKHOME}/conf/zoo.cfg #客戶化zoo.cfg配置 sed -i "s/clientPort=2181/clientPort=${ZKCLIENT_PORT}/g" ${ZKHOME}/conf/zoo.cfg sed -i "s#dataDir=/tmp/zookeeper#dataDir=${DATA_DIR}#g" ${ZKHOME}/conf/zoo.cfg sed -i "/dataLogDir/s/^/#/" ${ZKHOME}/conf/zoo.cfg echo "dataLogDir=${DATA_LOGDIR}" >>${ZKHOME}/conf/zoo.cfg #修改zookeeper-env.sh,指定運行日誌zookeeper.log路徑 sed -i "s#/var/log/zookeeper#${DATA_LOGDIR}#g" ${ZKHOME}/conf/zookeeper-env.sh #修改java.env,設置jvm參數,指定gc日誌路徑 sed -i "s#/var/log/zookeeper#${DATA_LOGDIR}#g" ${ZKHOME}/conf/java.env #服務器數量爲3個或5個爲集羣模式 if [ ${ZK_SRVNUM} -eq 3 ]||[ ${ZK_SRVNUM} -eq 5 ];then #根據端口數量判斷安裝方式 if [ ${CPORT_NUM} -eq 1 ];then #拆分IP地址列表,獲取本機ZK_ID for ((i=1;i<=${ZK_SRVNUM};i++));do eval IP_$i='`echo ${ZK_IPLIST}|awk -F, "{ print $"$i" }"`' # eval echo \$IP_$i eval IPTMP=\$IP_$i eval echo "server.${i}=\$IP_$i:${ZKLEADER_PORT}:${ZKCOM_PORT}">>${ZKHOME}/conf/zoo.cfg if [ "$HOST_IP" == "$IPTMP" ];then #當列表中的IP地址等於本機地址時,獲取當前i值做爲ID ZK_ID=${i} else continue fi done else ZK_ID=${NUM} while read ZK_INFO;do echo ${ZK_INFO}|awk -F, '{print "server."$1"="$2":"$4":"$5}'>>${ZKHOME}/conf/zoo.cfg done</home/workapp/zkinfo.cfg fi #客戶化myid echo "${ZK_ID}" >${DATA_DIR}/myid echo "zookeeper ID is ${ZK_ID}"|tee -a ${INSTALL_LOG} fi chown -R workapp:workapp ${ZKHOME} chown -R workapp:workapp ${DATA_LOGDIR} cat ${ZKHOME}/conf/zoo.cfg } function Check_install { retval=$? if [ $retval -eq 0 ];then echo "`date '+%Y%m%d %H:%M:%S'` zookeeper install SUCCESS!|${APP_NAME} ${MODULE_NAME} ${HOST_IP} ${ZKCLIENT_PORT} ${ZK_ID}|0"|tee -a ${INSTALL_LOG} else echo "`date '+%Y%m%d %H:%M:%S'` zookeeper install FAILED!|${APP_NAME} ${MODULE_NAME} ${HOST_IP} ${ZKCLIENT_PORT} ${ZK_ID}|1"|tee -a ${INSTALL_LOG} fi } function Start_check { su - workapp -c "sh ${ZKHOME}/bin/zkServer.sh start" sleep 10 su - workapp -c "sh ${ZKHOME}/bin/zkServer.sh status" netstat -anp|grep ${ZKCLIENT_PORT} } #根據端口數量判斷安裝方式,1個端口爲standalone或集羣模式,正常安裝; if [ ${CPORT_NUM} -eq 1 ];then Install_zk Check_install Start_check else #多個端口爲僞集羣模式,讀取zkinfo.cfg文件 while read ZK_INFO;do NUM=`echo ${ZK_INFO}|awk -F, '{print $1}'` IP=`echo ${ZK_INFO}|awk -F, '{print $2}'` ZKCLIENT_PORT=`echo ${ZK_INFO}|awk -F, '{print $3}'` ZKHOME=`echo ${ZK_INFO}|awk -F, '{print $6}'` DATA_LOGDIR=`echo ${ZK_INFO}|awk -F, '{print $7}'` DATA_DIR=`echo ${ZK_INFO}|awk -F, '{print $8}'` if [ "$IP" == "$HOST_IP" ];then Install_zk Check_install Start_check else continue fi done</home/workapp/zkinfo.cfg fi rm -f /home/workapp/zkinfo.cfg
執行腳本:
[root@bobo zookeeper]# sh install_zookeeper.sh -n 3 -a caiwu -l 192.168.10.25,192.168.10.26,192.168.10.27 -c 2181,2181,2181 -f 2888,2888,2888 -m 3888,3888,3888