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


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

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

    shell脚本中遇到的问题

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

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

            v2.0的方式,现在的方式是模块化日志方式,看代码

    #调试,调用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模块,通过和远程服务器交换,动态获取下载列表,根据需要保存到指定目录,优点:更具有扩展性,缺点是,服务器请求多

              在和远端服务器交换的时候设计到特殊字符及汉子的处理,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等

  • 相关阅读:
    How to install php 7.x on CentOS 7
    Azure新建的CentOS设置root账户的密码
    远程激活.NET REFLECTOR(不能断网)
    C# WebApi 配置复杂路由不生效的问题
    在Mac上激活Adobe产品
    WIN10更新后出现无法联网的问题
    Mac安装SSHFS挂载远程服务器上的文件夹到本地
    输入三个数值,输出其中的最大值和最小值
    登录接口,只为自己能尽快吐槽一下这段代码
    随手记
  • 原文地址:https://www.cnblogs.com/duplicatedcode/p/3058604.html
Copyright © 2020-2023  润新知