1、需求描述
对于上线步骤较为繁琐且注意的细节很多的项目,尽可能减少人为现场操作命令,让机器自动化实现上线功能尤为重要。
2、工具概述
工具启动后,会提示用户选择按系统指引执行(a)或输入指定指令执行(b)
每一步都会进行简单的用户交互(Y/N)后系统自动执行确认后的命令
工具包含的功能有:执行sql文件、发布应用程序、启动(重启)应用程序
3、工具结构
项目名称
etc/
sh/
help.sh
step.sh
top.sh
wrapper.sh
const.lst
dbinfo.cfg
file.cfg
func.cfg
step.lst
step_run.log
log/
source/
tool/
execSqlFile.sh
run.sh
目录或文件说明:
etc/ 配置文件存放目录
etc/sh 可执行的shell脚本,如help.sh,输出工具帮助信息;step.sh,输出项目部署步骤信息;top.sh,输出项目部署标题;wrapper.sh,自定义shell脚本的包装类,可实现shell脚本执行前后动作,如日志打印
etc/const.lst 工具常量文件
etc/dbinfo.cfg 数据库连接信息
etc/file.cfg 所有文件或目录常量文件
etc/func.cfg 公共函数
step.lst 项目部署步骤清单
step_run.log 步骤执行日志,日志内容包含步骤名称、执行状态(0成功 1失败)、开始时间、结束时间、耗时(秒)
log/ 日志目录
source/ 数据文件存放目录
tool/ 工具脚本存放目录,如execSqlFile.sh,传入可执行sql文件路径参数,用于 执行sql文件
run.sh 工具启动脚本
4、代码展示
run.sh
#!/bin/sh cd `dirname $0` #加载静态资源 . ./etc/const.lst . ./etc/dbinfo.cfg . ./etc/file.cfg . ./etc/func.cfg function init { clear #打印标题 ./etc/sh/top.sh checkstatus $? "输出标题" #打印操作步骤 ./etc/sh/step.sh checkstatus $? "输出操作步骤" } init if [ ! -f ${hkbaps_step_log} ]; then touch ${hkbaps_step_log} fi #加载操作步骤 declare -a array declare -a code declare -a cmd cnt=0 while read line do if [[ -n `echo ${line}|grep -v "^\s*$"` ]] && [[ "${line:0:1}" != "#" ]]; then let cnt=cnt+1 code[$cnt]="`lpad ${cnt} 3`" array[$cnt]="${code[$cnt]}-`echo ${line}|awk '{print $1}'`" cmd[$cnt]="`echo ${line}|awk '{print $2}'`" fi done < ${hkbaps_step} valid=0 match="" flag=1 index=1 #用户指令交互 while true do read -r -p "您是否选择按照操作步骤清单指引执行(a)或手工输入指定任务代码指令执行(b)? " inp case $inp in [aA]) while true do if [ ${valid} -eq 0 ]; then #判断最近是否存在未完成的任务 slog=`cat ${hkbaps_step_log}|grep -v "^\s*$"|tail -n 1` if [ -n "${slog}" ]; then step=`echo ${slog}|awk '{print $1}'` status=`echo ${slog}|awk '{print $2}'` if [ "${status}" == "1" ]; then match=${step} for((i=1;i<${#array[*]};i++)); do if [ "${array[$i]}" == "${step}" ]; then index=$i flag=0 break fi done if [ ${flag} -eq 1 ]; then match=${step} fi else flag=0 fi else flag=0 fi fi if [ ${flag} -eq 1 ]; then read -r -p "检测到未完成的任务:${match}不存在当前的操作步骤清单中,请输入指定任务代码指令或重新执行所有指令? " input case $input in [nN][oO]|[nN]) output "已取消操作" exit 1 ;; [uU][nN][dD][oO]|[uU]) read -r -p "确定要重新执行所有任务? [Y/N] " input2 case $input2 in [yY][eE][sS]|[yY]) match="" flag=0 index=1 valid=1 echo "" > ${hkbaps_step_log} ;; [nN][oO]|[nN]) output "已取消操作" valid=1 ;; [cC][lL][eE][aA][rR]|[cC]) init valid=1 ;; *) valid=1 echo -e "不合法的输入指令${input},请重新输入!" ;; esac ;; [sS][tT][eE][pP]|[sS]) ./etc/sh/step.sh ;; [hH][eE][lL][pP]|[hH]) ./etc/sh/help.sh ;; *) exists=0 for((i=1;i<${#code[*]};i++)); do tmp=`upper ${input}` if [ "${tmp}" == "${code[${i}]}" ]; then index=${i} exists=1 break fi done if [ ${exists} -eq 1 ]; then ${hkbaps_step_wrapper} ${array[${index}]} ${cmd[${index}]} valid=0 match="" flag=0 let index=index+1 else valid=1 echo -e "不合法的输入指令${input},请重新输入!" fi ;; esac else if [[ -n ${match} ]] && [[ ${index} -gt 1 ]]; then read -r -p "检测到未完成的任务:${match},是否直接执行? [Y/N] " input case $input in [yY][eE][sS]|[yY]) ${hkbaps_step_wrapper} ${array[${index}]} ${cmd[${index}]} valid=0 let index=index+1 match="" ;; [nN][oO]|[nN]) output "已取消操作" exit 1 ;; [uU][nN][dD][oO]|[uU]) read -r -p "确定要重新执行所有任务? [Y/N] " input2 case $input2 in [yY][eE][sS]|[yY]) match="" flag=0 index=1 valid=1 echo "" > ${hkbaps_step_log} ;; [nN][oO]|[nN]) valid=1 output "已取消操作" ;; *) valid=1 echo -e "不合法的输入指令${input},请重新输入!" ;; esac ;; [sS][tT][eE][pP]|[sS]) valid=1 ./etc/sh/step.sh ;; [hH][eE][lL][pP]|[hH]) valid=1 ./etc/sh/help.sh ;; [cC][lL][eE][aA][rR]|[cC]) valid=1 init ;; *) valid=1 echo -e "不合法的输入指令${input},请重新输入!" ;; esac else while [ ${index} -lt ${#array[*]} ]; do msg=${array[${index}]} slog=`cat ${hkbaps_step_log}|grep ${msg}|grep -v "^\s*$"|tail -n 1` if [ -n "${slog}" ]; then status=`echo ${slog}|awk '{print $2}'` if [ "${status}" == "0" ]; then read -r -p "步骤:${msg}已成功执行过,确认是否可以跳过该步骤? [Y/N] " input case $input in [yY][eE][sS]|[yY]) let index=index+1 ;; [nN][oO]|[nN]) break ;; [uU][nN][dD][oO]|[uU]) read -r -p "确定要重新执行所有任务? [Y/N] " input2 case $input2 in [yY][eE][sS]|[yY]) match="" flag=0 index=1 valid=1 echo "" > ${hkbaps_step_log} ;; [nN][oO]|[nN]) output "已取消操作" valid=1 ;; *) valid=1 echo -e "不合法的输入指令${input},请重新输入!" ;; esac ;; [sS][tT][eE][pP]|[sS]) valid=1 ./etc/sh/step.sh ;; [hH][eE][lL][pP]|[hH]) valid=1 ./etc/sh/help.sh ;; [cC][lL][eE][aA][rR]|[cC]) valid=1 init ;; *) valid=1 echo -e "不合法的输入指令${input},请重新输入!" ;; esac fi else break fi done let t=index-1 if [[ ${t} -gt 0 ]] && [[ ${index} -lt ${#array[*]} ]]; then msg=${array[${t}]} read -r -p "步骤:${msg}已执行完毕,确认是否可以执行下一步骤:${array[${index}]}? [Y/N] " input case $input in [yY][eE][sS]|[yY]) ;; [nN][oO]|[nN]) output "已取消操作" exit 1 ;; [uU][nN][dD][oO]|[uU]) read -r -p "确定要重新执行所有任务? [Y/N] " input2 case $input2 in [yY][eE][sS]|[yY]) match="" flag=0 index=1 valid=1 echo "" > ${hkbaps_step_log} ;; [nN][oO]|[nN]) output "已取消操作" valid=1 ;; *) valid=1 echo -e "不合法的输入指令${input},请重新输入!" ;; esac ;; [sS][tT][eE][pP]|[sS]) valid=1 ./etc/sh/step.sh ;; [hH][eE][lL][pP]|[hH]) valid=1 ./etc/sh/help.sh ;; [cC][lL][eE][aA][rR]|[cC]) valid=1 init ;; *) valid=1 echo -e "不合法的输入指令${input},请重新输入!" ;; esac fi if [ ${index} -lt ${#array[*]} ]; then if [ ${index} -eq 1 ]; then msg=${array[${t}]} read -r -p "步骤:${array[${index}]},确认是否开始执行? [Y/N] " input case $input in [yY][eE][sS]|[yY]) ;; [nN][oO]|[nN]) output "已取消操作" exit 1 ;; [sS][tT][eE][pP]|[sS]) valid=2 ./etc/sh/step.sh ;; [hH][eE][lL][pP]|[hH]) valid=2 ./etc/sh/help.sh ;; [cC][lL][eE][aA][rR]|[cC]) valid=2 init ;; *) valid=2 echo -e "不合法的输入指令${input},请重新输入!" ;; esac fi if [ ${valid} -ne 2 ]; then ${hkbaps_step_wrapper} ${array[${index}]} ${cmd[${index}]} valid=0 let index=index+1 match="" fi else output "任务执行完毕!" exit 1 fi fi fi done ;; [bB]) while true do read -r -p "请输入步骤指令代码: " input case $input in [nN][oO]|[nN]) output "已取消操作" exit 1 ;; [sS][tT][eE][pP]|[sS]) ./etc/sh/step.sh ;; [hH][eE][lL][pP]|[hH]) ./etc/sh/help.sh ;; [cC][lL][eE][aA][rR]|[cC]) init ;; *) exists=0 for((i=1;i<${#code[*]};i++)); do tmp=`upper ${input}` if [ "${tmp}" == "${code[${i}]}" ]; then index=${i} exists=1 break fi done if [ ${exists} -eq 1 ]; then ${hkbaps_step_wrapper} ${array[${index}]} ${cmd[${index}]} else echo -e "不合法的输入指令${input},请重新输入!" fi ;; esac done ;; [nN][oO]|[nN]) output "已取消操作" exit 1 ;; [sS][tT][eE][pP]|[sS]) ./etc/sh/step.sh ;; [hH][eE][lL][pP]|[hH]) ./etc/sh/help.sh ;; [cC][lL][eE][aA][rR]|[cC]) init ;; *) echo -e "不合法的输入指令${input},请重新输入!" ;; esac done
etc/const.lst
sys_name=XXX系统 sys_code=XXX sys_task=上线操作 sys_author=XXX sys_user=XXX sys_skin=[44\;37 LANG="zh_CN.GBK" NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
etc/dbinfo.cfg
db_dump_username=XXX db_dump_uo_username=XXX db_username=XXX db_password=XXX db_instance=XXX db_link=${db_username}/${db_password}@${db_instance}
etc/file.cfg
#步骤清单 step=etc/step.lst #步骤执行日志 step_log=etc/step_run.log #步骤执行包装器 step_wrapper=./etc/sh/wrapper.sh #数据库信息检查语句 db_check_sql=source/env_db.sql #数据库信息检查脚本 db_check=./etc/sh/env_db.sh #校验01 check_01=source/check_01.sql #校验02 check_02=source/check_02.sql #校验03 check_03=source/check_03.sql
etc/func.cfg
#!/bin/sh #日志文件 export logfile=log/`date +%Y%m%d`.log #info级别控制台日志 function output { msg=$1 skin=$2 if [ -f "${msg}" ]; then echo `date` >> ${logfile} cat ${msg} >> ${logfile} cat ${msg} else if [ -n "${skin}" ]; then echo -e "\033${skin}${msg}\033[0m" else echo -e ${msg} fi echo -e "`date` ${msg}" >> ${logfile} fi } function title { msg=$1 skin=$2 if [ -n "${skin}" ]; then echo -e "\n\033${skin}\;1m${msg}\033[0m\n" else echo -e "\n\033[1m${msg}\033[0m\n" fi echo -e "`date` \n${msg}\n" >> ${logfile} } function success { msg=$1 if [ ! -n "${msg}" ]; then msg=执行成功 fi output ${msg} } function error { msg=$1 if [ ! -n "${msg}" ]; then msg=执行失败 fi output ${msg} exit 1 } function checkstatus { code=$1 msg=$2 if [ ${code} -ne 0 ]; then output ${msg}异常:${code} exit 1 fi } function printchar { n=$1 c=$2 s="" if [ ! -n "${n}" ]; then n=20 fi if [ ! -n "${c}" ]; then c="_" fi for((i=1;i<=${n};i++)); do s="${s}${c}" done echo -e ${s} } function seperate { echo "" echo `printchar "-" 300` echo "" } function lpad { char=$1 len=$2 fill=$3 if [ -n "${char}" ]; then if [ ! -n "${len}" ]; then len=8 fi if [ ! -n "${fill}" ]; then fill="0" fi size=${#char} let m=len-size s="" for((i=1;i<=${m};i++)); do s="${s}${fill}" done echo ${s}${char} fi } function lower { msg=$1 if [ -n "${msg}" ]; then if [ -f "${msg}" ]; then cat ${msg}|tr A-Z a-z else echo ${msg}|tr A-Z a-z fi fi } function upper { msg=$1 if [ -n "${msg}" ]; then if [ -f "${msg}" ]; then cat ${msg}|tr a-z A-Z else echo ${msg}|tr a-z A-Z fi fi } #日志文件错误信息检查 function checklog { reg=$1 log=$2 msg="" if [ ! -f "${log}" ]; then log=${logfile} msg=`cat ${log}|grep -i ${reg}` else msg=`cat ${logfile}|grep -i ${reg}` fi if [ ${#msg} -gt 0 ]; then echo "日志文件${log},发现报错信息:${msg}" exit 1 fi } function execSqlFile { dbconn=$1 dbfile=$2 err=$3 if [ ! -n "${dbconn}" ]; then error "数据库连接信息缺失,请检查" fi if [ ! -f "${dbfile}" ]; then error "sql文件${dbfile}不存在,请检查" fi if [ ! -n "${err}" ]; then err=ORA- fi read -r -p "即将在数据库环境${dbconn}中执行sql文件${dbfile}? [Y/N] " input case $input in [yY][eE][sS]|[yY]) sqlplus -S /nolog<<EOF conn ${dbconn} spool ${logfile} append @${dbfile} spool off quit EOF checklog ${err} ;; [nN][oO]|[nN]) echo "已取消操作" ;; *) echo "Invalid input..." exit 1 ;; esac } function execDSqlFile { dbconn=$1 dbfile=$2 err=$3 if [ ! -n "${dbconn}" ]; then error "数据库连接信息缺失,请检查" fi if [ ! -f "${dbfile}" ]; then error "sql文件${dbfile}不存在,请检查" fi if [ ! -n "${err}" ]; then err=ORA- fi sqlplus -S /nolog<<EOF conn ${dbconn} spool ${logfile} append @${dbfile} spool off quit EOF } function executeSql(){ dbconn=$1 sql=$2 err=$3 if [ ! -n "${dbconn}" ]; then error "数据库连接信息缺失,请检查" fi if [ ! -n "${sql}" ]; then error "sql脚本${sql}缺失,请检查" fi if [ -f "${sql}" ]; then sql=`cat ${sql}` fi lst=${sql: -1} if [ "${lst}" != ";" ]; then sql="${sql};" fi if [ ! -n "${err}" ]; then err=ORA- fi read -r -p "即将在数据库环境${dbconn}中执行sql语句:${sql}? [Y/N] " input case $input in [yY][eE][sS]|[yY]) sqlplus -S /nolog<<EOF conn ${dbconn} spool ${logfile} append ${sql} spool off quit EOF checklog ${err} ;; [nN][oO]|[nN]) echo "已取消操作" ;; *) echo "Invalid input..." exit 1 ;; esac } function querySingle(){ dbconn=$1 sql=$2 err=$3 if [ ! -n "${dbconn}" ]; then error "数据库连接信息缺失,请检查" fi if [ ! -n "${sql}" ]; then error "sql脚本${sql}缺失,请检查" fi if [ -f "${sql}" ]; then sql=`cat ${sql}` fi lst=${sql: -1} if [ "${lst}" != ";" ]; then sql=${sql}; fi if [ ! -n "${err}" ]; then err=ORA- fi read -r -p "即将在数据库环境${dbconn}中执行sql语句:${sql}? [Y/N] " input case $input in [yY][eE][sS]|[yY]) result=`sqlplus -S /nolog<<EOF set heading off feedback off pagesize 0 verify off echo off conn ${dbconn} spool ${logfile} append ${sql} spool off quit EOF` checklog ${err} echo ${result} ;; [nN][oO]|[nN]) echo "已取消操作" ;; *) echo "Invalid input..." exit 1 ;; esac } function impDump(){ dbconn=$1 file=$2 fromuser=$3 touser=$4 err=$5 if [ ! -n "${dbconn}" ]; then error "数据库连接信息缺失,请检查" fi if [ ! -f "${file}" ]; then error "导入的dump文件${file}缺失,请检查" fi if [ ! -n "${fromuser}" ]; then error "导入时数据库来源用户缺失,请检查" fi if [ ! -n "${touser}" ]; then error "导入时数据库目标用户缺失,请检查" fi if [ ! -n "${err}" ]; then err=ORA- fi read -r -p "即将在数据库环境${dbconn}中执行dump导入,导入文件:${file},来源用户:${fromuser},目标用户:${touser}? [Y/N] " input case $input in [yY][eE][sS]|[yY]) tmp="${logfile}.imp.`date +%H%M%S`" imp ${dbconn} file=${file} log=${tmp} STATISTICS=NONE data_only=y fromuser=${fromuser} touser=${touser} checklog ${err} ${tmp} ;; [nN][oO]|[nN]) echo "已取消操作" ;; *) echo "Invalid input..." exit 1 ;; esac } function exportDump(){ dbconn=$1 file=$2 lst=$3 err=$4 if [ ! -n "${dbconn}" ]; then error "数据库连接信息缺失,请检查" fi if [ ! -n "${file}" ]; then error "导出dump文件名缺失,请检查" fi if [ ! -f "${lst}" ]; then error "导出的表清单文件${lst}不存在,请检查" fi if [ ! -n "${err}" ]; then err=ORA- fi read -r -p "即将在数据库环境${dbconn}中执行dump导出,导出文件:${file},导出表清单:`cat ${lst}`? [Y/N] " input case $input in [yY][eE][sS]|[yY]) tabs="" while read line do tabs="${tabs},`echo ${line}|awk '{print $1}'`" done < ${lst} if [ -n "${tabs}" ]; then tabs=${tabs:1} tmp="${logfile}.exp.`date +%H%M%S`" exp ${dbconn} file=${file} log=${tmp} tables=${tabs} checklog ${err} ${tmp} fi ;; [nN][oO]|[nN]) echo "已取消操作" ;; *) echo "Invalid input..." exit 1 ;; esac }
etc/step.lst
环境信息检查 ./etc/sh/env.sh 应用程序启动(或重启) ./etc/sh/app_startup.sh
etc/sh/help.sh
#!/bin/sh #帮助指南 cd `dirname $0` cd ../../ . ./etc/const.lst . ./etc/file.cfg . ./etc/func.cfg output 帮助指南 "${sys_skin};1m" output "" output "a:按照操作步骤指引执行" output "b:选择手工输入指令执行" output "c:清空控制台" output "h:查看帮助指南" output "n:取消当前操作" output "s:查看操作步骤" output "u:重新执行(注:适合选择操作指引的方式)" output "y:确认当前系统提示" output ""
etc/sh/top.sh
#!/bin/sh #输出控制台顶部信息 cd `dirname $0` cd ../../ . ./etc/const.lst . ./etc/file.cfg . ./etc/func.cfg header=`printchar 30` header="${header}${sys_name}(${sys_code}) - ${sys_task}${header}" echo -e "\033${sys_skin};1m ${header}\033[0m\033${sys_skin};4m 操作人:${sys_author}\033[0m" echo ""
etc/sh/step.sh
#!/bin/sh #输出执行步骤信息 cd `dirname $0` cd ../../ . ./etc/const.lst . ./etc/file.cfg . ./etc/func.cfg output 执行步骤 "${sys_skin};1m" cnt=0 while read line do if [ -n "${line}" ] && [[ "${line:0:1}" != "#" ]]; then let cnt=cnt+1 output ${cnt}、`lpad ${cnt} 3`-`echo ${line}|awk '{print $1}'` fi done < ${hkbaps_step} output "\n"
etc/sh/wrapper.sh
#!/bin/sh #步骤执行包装器 cd `dirname $0` cd ../../ . ./etc/const.lst . ./etc/file.cfg . ./etc/func.cfg step=$1 cmd=$2 if [ ! -n ${step} ]; then error "包装器中执行步骤不能为空,请检查!" elif [ ! -n ${cmd} ]; then error "执行步骤:${step}未配置对应执行脚本,请检查" else output "" output ${step} "${sys_skin};1m" output "" bdate=`date +%Y%m%d%H%M%S` sh ${cmd} tmp=$? output "" edate=`date +%Y%m%d%H%M%S` cost=$(( edate-bdate )) result="" if [[ ${tmp} -ne 0 ]] || [[ ${msg} -ne 0 ]]; then result="${step}\t1\t${bdate}\t${edate}\t${cost}(秒)" else result="${step}\t0\t${bdate}\t${edate}\t${cost}(秒)" fi echo -e ${result} >> ${hkbaps_step_log} fi
etc/sh/env_db.sh
#!/bin/sh #数据库信息检查 cd `dirname $0` cd ../../ . ./etc/const.lst . ./etc/dbinfo.cfg . ./etc/file.cfg . ./etc/func.cfg execDSqlFile ${db_link} ${hkbaps_db_check_sql}
etc/sh/app_startup.sh
#!/bin/sh #应用程序启动(或重启) cd `dirname $0` cd ../../ . ./etc/const.lst . ./etc/file.cfg . ./etc/func.cfg export LANG=en_US.UTF-8 echo "LANG:$LANG" u=`whoami` if [ "${u}" != "${sys_user}" ]; then output "当前登录用户${u}与要求的用户${sys_user}不符" read -r -p "当前登录用户${u}与要求的用户${sys_user}不符,确认是否用该用户启动(重启)应用? [Y/N] " input case $input in [yY][eE][sS]|[yY]) ;; [nN][oO]|[nN]) output "已取消操作" exit 1 ;; *) echo -e "不合法的输入指令${input},请重新输入!" ;; esac fi #停服务 #停止web应用服务 web_log=`ps -ef|grep "Dcatalina.home=${app_web}"|grep -v grep` if [ -n "${web_log}" ]; then sh ${app_web}/bin/shutdown.sh fi cnt=0 while [ ${cnt} -lt 3 ] do web_log=`ps -ef|grep "Dcatalina.home=${app_web}"|grep -v grep` if [ -n "${web_log}" ]; then let cnt=cnt+1 sleep 2 else break fi done web_log=`ps -ef|grep "Dcatalina.home=${app_web}"|grep -v grep` if [ -n "${web_log}" ]; then output ${web_log} progress=`echo ${web_log}|awk '{print $2}'` read -r -p "web应用停止服务耗时太久,是否强制停止进程-${progress}? [Y/N] " input case $input in [yY][eE][sS]|[yY]) kill -9 ${progress} ;; [nN][oO]|[nN]) output "已取消操作" exit 1 ;; *) echo -e "不合法的输入指令${input},请重新输入!" ;; esac fi #停止server应用服务 server_log=`ps -ef|grep "Dcatalina.home=${app_server}"|grep -v grep` if [ -n "${server_log}" ]; then sh ${app_server}/bin/shutdown.sh fi cnt=0 while [ ${cnt} -lt 3 ] do server_log=`ps -ef|grep "Dcatalina.home=${app_server}"|grep -v grep` if [ -n "${server_log}" ]; then let cnt=cnt+1 sleep 2 else break fi done server_log=`ps -ef|grep "Dcatalina.home=${app_server}"|grep -v grep` if [ -n "${server_log}" ]; then output ${server_log} progress=`echo ${server_log}|awk '{print $2}'` read -r -p "server应用停止服务耗时太久,是否强制停止进程-${progress}? [Y/N] " input case $input in [yY][eE][sS]|[yY]) kill -9 ${progress} ;; [nN][oO]|[nN]) output "已取消操作" exit 1 ;; *) echo -e "不合法的输入指令${input},请重新输入!" ;; esac fi #启服务 sh ${app_server}/bin/startup.sh && sh ${app_web}/bin/startup.sh cnt=0 while [ ${cnt} -lt 3 ] do server_log=`ps -ef|grep "Dcatalina.home=${app_server}"|grep -v grep` if [ -n "${server_log}" ]; then progress=`echo ${server_log}|awk '{print $2}'` output "server应用服务启动成功,进程号:${progress}" break else let cnt=cnt+1 sleep 2 fi done cnt=0 while [ ${cnt} -lt 3 ] do web_log=`ps -ef|grep "Dcatalina.home=${app_web}"|grep -v grep` if [ -n "${web_log}" ]; then progress=`echo ${web_log}|awk '{print $2}'` output "web应用服务启动成功,进程号:${progress}" break else let cnt=cnt+1 sleep 2 fi done