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

shell脚本规划化模板的更多相关文章

  1. shell脚本结构化语句

    本文中记录一下shell中的两种循环语句:for和while for循环 for循环是linux shell中最常用的结构,for循环有三种结构:1.列表for循环.2.不带列表for循环.3.C风格 ...

  2. 运维与自动化系列③自动化部署基础与shell脚本实现

    自动化部署基础与shell脚本实现 关于自动化的基础知识: 1.1:当前代码部署的实现方式: 运维纯手工scp到web服务器纯手工登录git服务器执行git pull或svn服务器执行svn upda ...

  3. 【Hadoop离线基础总结】oozie调度shell脚本

    目录 1.解压官方提供的调度案例 2.创建工作目录 3.拷贝任务模板到工作目录当中去 4.随意准备一个shell脚本 5.修改模板下的配置文件 6.上传调度任务到hdfs上面去 7.执行调度任务 1. ...

  4. 《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令

    许多程序要就对shell脚本中的命令施加一些逻辑控制流程. 结构化命令允许你改变程序执行的顺序.不一定是依次进行的 12.1 使用if-then语句 如下格式: if command then     ...

  5. shell脚本处理长参数的模板

    shell脚本处理长参数的模板 一个shell模板,处理命令行参数,支持长短参数: #!/bin/bash # # FILE: kvm-clone-v2.sh # # DESCRIPTION: Clo ...

  6. Shell脚本常用模板

    作为一个运维人员编写Shell脚本是很平常的,一个格式好的脚本不仅赏心悦目,后期自己和别人也易于维护. 下面的脚本就是我自己的shell编写格式,如下: [root@mini05 -]# cat te ...

  7. shell脚本模板----自动生成开头注释信息

    每当我们新建一个shell脚本都要去写一些繁琐的注释信息,这会浪费掉我们很多的时间,有没有感觉很痛苦呢? 哈哈 下面给大家分享一个shell脚本的模板文件,把它拷贝到用户的家目录下并命名成  .vim ...

  8. Shell脚本学习笔记之(自动填充函数模板)

    其实,vii 就是写的一个脚本,跟 vi 没半毛钱关系,只不过借用一下这个名字而已.那这个脚本长什么样呢?look: 下面来详细的解析上面的代码,来看第1行: #!/bin/bash 这是Shell脚 ...

  9. shell脚本编程-使用结构化命令(if/else)(转)

    11.1 使用if-then语句 格式如下 if语句会执行if行定义的那个命令,如果该命令的退出状态码是0,则then部分的语句就会执行,其他值,则不会   1 2 3 4 if command th ...

随机推荐

  1. 【开源】分享2011-2015年全国城市历史天气数据库【Sqlite+C#访问程序】

    由于个人研究需要,需要采集天气历史数据,前一篇文章:C#+HtmlAgilityPack+XPath带你采集数据(以采集天气数据为例子),介绍了基本的采集思路和核心代码,经过1个星期的采集,历史数据库 ...

  2. 谈谈一些有趣的CSS题目(二)-- 从条纹边框的实现谈盒子模型

    开本系列,讨论一些有趣的 CSS 题目,抛开实用性而言,一些题目为了拓宽一下解决问题的思路,此外,涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题中有你感觉 ...

  3. Oracle碎碎念~2

    1. 如何查看表的列名及类型 SQL> select column_name,data_type,data_length from all_tab_columns where owner='SC ...

  4. hadoop2.7之Mapper/reducer源码分析

    一切从示例程序开始: 示例程序 Hadoop2.7 提供的示例程序WordCount.java package org.apache.hadoop.examples; import java.io.I ...

  5. Aaron Stannard谈Akka.NET 1.1

    Akka.NET 1.1近日发布,带来新特性和性能提升.InfoQ采访了Akka.net维护者Aaron Stannard,了解更多有关Akka.Streams和Akka.Cluster的信息.Aar ...

  6. 原生js+css3实现图片自动切换,图片轮播

    运用CSS3transition及opacity属性 制作图片轮播动画 自己这两天根据用js来控制触发CSS3中transition属性,从而写出来的以CSS3动画为基础,js控制过程的图片轮播 运用 ...

  7. iOS UITableView 与 UITableViewController

    很多应用都会在界面中使用某种列表控件:用户可以选中.删除或重新排列列表中的项目.这些控件其实都是UITableView 对象,可以用来显示一组对象,例如,用户地址薄中的一组人名.项目地址. UITab ...

  8. Atitit.如何建立研发体系

    Atitit.如何建立研发体系 组织,流程,prj..Mana  oppm 发管理是一个完整的管理体系,从结构上来讲,它主要由四个方面的内容构架而成:组织结构与岗位设置 管理流程与工作流程..项目及管 ...

  9. nginx启动报错:/usr/local/nginx/sbin/nginx: error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory

    查看依赖库:

  10. 清除打印机队列中无法清除的任务 & 清空打印池

    故障现象典型表现为以下两种情况 1.当打印任务开始进行时,这些打印任务便被保存在打印作业列表(也称打印队列)内.如果打印机因意外暂停(如打印机未连接)而未完成打印任务,则该打印任务将列入打印队列,并且 ...