我在写shell自动部署脚本碰到的问题

如题,最先接触shell脚本是大学的时候,感受好复杂,最近几年工做中也零零散散的接触过不少,不少都是网上找资源进行解决,这两天在写自动部署的初始化脚本,感受仍是挺多不足的。linux

shell脚本写的有点c语言的感受,是过程语言,可是如何模块化就很是重要了,首先个人第一个版本是完成了从远端服务器获取资源文件,一键部署tomcat,jdk,生成backup目录,log目录,web目录,script目录,tools目录,生成tomcat自启动脚本。以及和远端服务器的交互等。整个shell脚本写下来花了半天的时间,一个方法搞定所有,没有错误处理机制,没有合适的操做日志。全部就有了下面的重构。web

shell脚本中遇到的问题shell

    1.执行脚本的日志打印,错误记录,相似于日志机制没有编程

       v1.0的版本采用的日志方式是,直接print,遇到错误直接returnapi

        v2.0的方式,如今的方式是模块化日志方式,看代码tomcat

#调试,调用wget记录日志 debug() { if [ $global_is_debug = "true" ];then debug_str=$1
      echo "debug:##### ${debug_str} #####\n"
   fi } #错误,调用wget记录日志 error() { echo "error:########### $1 ############\n" }

    2.用wget方式和远程服务器交互,特殊字符处理服务器

          v1.0:直接wget –i 一个列表,而后存到本地,一系列操作后,删除文件模块化

               优势是,简单粗暴,缺点是不能适应自动化部署工具

          v2.0:封装wget模块,经过和远程服务器交换,动态获取下载列表,根据须要保存到指定目录,优势:更具备扩展性,缺点是,服务器请求多post

          在和远端服务器交换的时候设计到特殊字符及汉子的处理,v2.0封装了一个urlencode方法,进行转码。代码以下:

#进行编码,编码结果放在全局变量里面 urlEncode() { #须要被编码的字符串 encode_str_params1=$1 debug "${encode_str_params1}" #编码 global_encode_str=`echo "${encode_str_params1}" | tr -d '\n' | xxd -plain | sed 's/\(..\)/%\1/g'` return }

补充一点:wget 对于请求的url带有特殊字符的处理,我后台采用的是struts2,提供的api接口带有 例如 http//t.cn/api/linux!errorDebug?xx=oo&oo=xx

你采用传统的方式都会报bad参数的错误,调试好久都未果,个人经验是,采用post方式,若是有特殊字符的 须要用 ‘’ 包含起来,好比上述的。

下面的代码中wgetPost是封装了一个将请求文件存到指定目录的功能,文件名命名方式为 debug_时间_全局的自增字段。

第一行请求变量参数里有特殊字符,后面跟着的字符串也须要用‘’包含起来,具体为何,应该是shell的解释器就是这样规定的,‘’小括号里不能包含变量

wgetPost ${global_log_url}'logDebug?' ${global_project_log_debug_path}/ "debug_"$(date +%Y-%m-%d-%H-%M-%S)"_${global_debug_file_log_num}" ${inner_post_data}
 
 

#wget简单封装
#inner_url: 访问地址
#inner_dir: 目录
#inner_file: 文件名称
#inner_post_data 请求的数据
wgetPost()
{
inner_url=$1
inner_dir=$2
inner_file=$3
inner_post_data=$4
#容错处理
mkdir -p -m 777 ${inner_dir}
wget --post-data="${inner_post_data}" ${inner_url} -O ${inner_dir}${inner_file}".bk" -o /dev/null
inner_bytes=$(du -s ${inner_dir}${inner_file}.bk | awk '{print $1}')
if [ $inner_bytes -ne 0 ];then
cp -rf ${inner_dir}${inner_file}.bk ${inner_dir}${inner_file}
else
echo "wget ${inner_url} failed"
fi
}

3.sed命令在处理特殊字符替换的时候处理

       sed –i ‘s/a/b/g’ 通常是这种方式,可是若是遇到要替换的字符或者被替换的字符有*_/ \的时候,就不适用了,解决的方式是利用#号

     能够通用点,就是将源字符串,替换为目标字符串

source_str="abc" target_str="xxoo"

sed -i "s#${source_str}#${target_str}#g"  str.txt

    4.合理的代码编程规范

        编码规范很重要,v1.0版本写的比较随意,变量名比较混乱,维护花时间,

      v2.0注意这个问题,目前的规范是:

            1.全部的静态变量 前缀为 static_xx_xx

            2.全部的全局变量 前缀为 global_xx_oxx

            3.参数为 in_xx_xx

            4.方法内的局部变量为 inner_xxdf

            5.方法的命名规则遵循通俗易懂

            6.模块化操做,讲究代码

    5.目录的权限问题

          目录的权限问题是个很是头疼的问题,由于全部的操做为root操做,若是控制到很是精细力度的权限,这块都要头疼死,在v2.0稳定的基础上,保证自动部署系统的如期完成,顶级目录不开放修改,子目录为777权限,任何人能够修改,等自动部署系统前台完成后,就能够彻底回收权限了

    6.日志记录的级别

         日志这个东西很重要,v1.0的版本是采用打印到控制台的方式

        v2.0采用方式是进行级别控制 ,分为debug 和error 方式,debug模式有开关配置,error模式之间输出,而且经过wget方式入库,及时反馈到前台

    7.应用服务器及依赖环境的准备方式

   依赖环境也很重要,自动部署讲究一个自动部署,统一规范,可是线上的版本不少,好比jdk有1.5,1.6,1,7 同时 tomcat也会有各类版本,memcache等都各不相同。为了统一,首先取线上稳定的tomcat版本清理后做为基础版本,例如tomcat.7.39.tar.gz,解压后利用脚本动态更改配置后就可使用,还有jdk的安装目录等,如今的作法就是 把线上的版本都收集起来,经过后台网页工具进行选择,自定义配置,首先应用环境的基础版本是清洁版本,配置文件已经进行过优化,只须要替换几个常量便可,这里完成的是,1.tomcat的端口号,关闭端口,启动时的jdk目录,自启动脚本的tomcat-home等

相关文章
相关标签/搜索