shell脚本规划化模板
Linux运维过程中,shell脚本是不可缺少的工具,但是每个运维人员编程的习惯都不一样,很多时候就是实现某个功能,写出来的脚本都是烂七八糟的。
脚本必须规范化,应该从以后几个方面着手:
  1、脚本必须记录日志,尽可能多的把执行命令操作写入日志当中,有便于日后可以追踪;
  2、脚本尽可能实现函数化模块化,函数名具有可读性;
  3、脚本必须要有传入参数;
  4、脚本执行必须是单进程的,即该脚本某个时间段只能运行一次;
  5、脚本执行过程中必须加锁机制;
  6、脚本注释是不可缺少的;
  7、脚本最好统一入口(main函数),个人喜好;
大致分为这7点,运维必须规范化流程化,不做流氓运维,对自己工作负责,也便于其他同事方便查看或接手,我个人不推崇脚本复杂化,搞一堆大家看不懂的。
举例说明,上线是运维不可缺少的工作,本人测试实现一个很简单的功能:
1、jboss容器发布java代码(不考虑配置文件更新)
      1)关闭服务;
	  2)拷贝代码至指定目录;
	  3)启动服务;
2、服务器上面开好几个jboss实例(按业务模块化),自动识别出每个容器(目录:/data/)
3、根据模块化发布版本,每次只更新一个业务模块版本
#!/bin/bash
#######################################################
# $Name:         release.sh	                                
# $Version:      v1.0                                 
# $Function:     release for jboss Script 
# $Author:       Verrion Jian 
# $Create Date:  2016-09-22 
# $Description:  Sub module to release for firm 
#######################################################
# 定义脚本环境变量
SHELL_NAME="release.sh"
SHELL_DIR="/data/scripts"
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"
LOCK_FILE="/tmp/${SHELL_NAME}.lock"
PACKAGE_DIR="/data/code"
# 记录日志 
log_output(){
      LOG_INFO=$1
      echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" >> ${SHELL_LOG}
}
# 脚本用法,自动化列出服务器上面存在的所有实例
usage(){
      get_modules
      str=`echo ${module_array[@]} |sed s/[[:space:]]/‘|‘/g`
      echo $"Usage: $0 [$str]" && exit
}
# 添加锁文件
lock(){
      touch ${LOCK_FILE}
}
# 删除锁文件
unlock(){
      rm -f ${LOCK_FILE}
}
# 判断代码临时目录和文件是否存在
is_package_exist(){
      if [ ! -d $PACKAGE_DIR ];then
	    log_output "The script exec as insufficient --> The release directory is non-existent"
          echo "The release directory is non-existent" && exit
      fi
      package_num=`ls $PACKAGE_DIR |wc -l`
      if [ $package_num -eq 0 ];then
	    log_output "The script exec as insufficient --> The packages for release is empty"
            echo "The packages for release is empty,please check directory:"$PACKAGE_DIR" and upload packages" && exit
      fi
}
# 列出服务器上面jboss容器个数
get_container(){
      container_name=`ls -l /data/ |grep jboss | awk ‘{print $9}‘|xargs`
}
# 列出实例模块信息,进程号等(如:test_login.war为java代码包)
get_modules(){
      get_container
      for i in $container_name
            do
                  war_num=`ls /data/$i/server/default/deploy/test*war | wc -l`
                  if [ $war_num -ne 1 ];then
	                log_output "The container deploy to not standard--> Num of the war_package can only one"
                        echo "The container deploy to not standard--> Num of the war_package can only one" && exit
                  else
                        war_name=`ls /data/$i/server/default/deploy/test*war | cut -d / -f7 | cut -d - -f1`
                        pid=`ps -ef |grep $i |grep -v grep |awk ‘{print $2}‘`
                        module_name=$war_name" "$module_name
                        pids=$pid" "$pids
                        jboss_name=$i" "$jboss_name
 	          fi
            done
      module_array=($module_name)
      pid_array=($pids)
      jboss_array=($jboss_name)
}
# 模块化发布上线
release_module(){
      # ensure a process is running at best
      if [ -f "$LOCK_FILE" ];then
            log_output "${SHELL_NAME} is running"
            echo "${SHELL_NAME}" is running && exit
      fi
      # ensure the package exist
      is_package_exist
    
      # denfie varchar
      packagename=$1
      packagenum=$2
      packagenum=`expr $packagenum - 1`
      target_pid=${pid_array[$packagenum]}
      target_jboss=${jboss_array[$packagenum]}
      target_dir="/data/$target_jboss/server/default/deploy"
      package_str=`ls $PACKAGE_DIR`
      log_output "release module for platform system start"
      lock
      if [[ $package_str =~ $packagename ]];then
            #kill -9 $target_pid
            echo "kill -9 $target_pid"
            log_output "kill -9 $target_pid"
            #echo $target_pid
            sleep 3
            #rm -rf $target_dir/$packagename*
            echo "rm -rf $target_dir/$packagename*"
            log_output "rm -rf $target_dir/$packagename*"
            #ls $target_dir/$packagename*
            #cp -r $PACKAGE_DIR/$packagename* $target_dir
            echo "cp -r $PACKAGE_DIR/$packagename* $target_dir"
            log_output "cp -r $PACKAGE_DIR/$packagename* $target_dir"
            #ls $PACKAGE_DIR/$packagename* 
      else 
            log_output "The package of publish directory is not found"
            echo "The package of publish directory is not found" && exit
      fi
      log_output "release module for platform system stop"
      unlock
}
# Main函数入口
main(){
      tag=0
      if [ -z $1 ];then
            usage
      fi
      get_modules
      for i in $module_name
        do
              let count+=1
	      if [ $i = $1 ];then
                    pkgname=$1
                    pkgnum=$count
                    release_module "$pkgname" "$pkgnum"
                    tag=1
                    break
              fi
        done
      if [ $tag -eq 0 ];then
            module_name=""
            usage
      fi 
}
# 执行脚本
main $1
原文:http://www.cnblogs.com/verrion/p/shellscript_standardized.html