经典的运维脚本三步曲

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 经典的运维脚本三步曲

经典的运维脚本三步曲

无论是应用运维,还是数据库运维,均可以分为“人肉”-“自动化”-“智能化”阶段,其中自动化阶段,主要是将一些人做的操作,尤其是一些重复性操作,封装为程序,一方面避免重复性操作,另一方面提高执行效率。自动化实现的过程中,经常使用的,可能就是shell脚本了,前段时间,从一个微信公众号,学习了赵班长写的一篇小文,循序渐进的方式,介绍了shell运维脚本的编写,小脚本有大智慧,几十行代码,夹杂着系统设计、代码规范等细节,值得学习。

以下脚本参考的原文:《》,用shell脚本模拟mysql备份过程,循序渐进的三个脚本。

脚本一:记录日志的shell脚本,shell_template_1.sh

#!/bin/bash

SHELL_NAME="shell_template_1.sh" SHELL_DIR="/home/oracle/scripts/shell" SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"

shell_log() {         LOG_INFO=$1         echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" ${SHELL_LOG} }

shell_log "shell beginning, write log test" shell_log "sehll success, write log test"

负责打印日志的函数,shell_log(),接受第一个参数,作为需要打印的日志内容,shell_log()中定义了日志输出的格式(年-月-日 时-分-秒 : 脚本名称 : 日志内容),日志文件路径,则由$SHELL_LOG变量定义。

执行shell_template_1.sh,生成日志文件shell_template_1.sh.log,

vi shell_template_1.sh.log

2017-10-11 11-34-39 : shell_template_1.sh : shell beginning, write log test 2017-10-11 11-34-39 : shell_template_1.sh : sehll success, write log test

脚本二:直接执行的脚本很危险,要提示用户如何使用脚本,shell_template_2.sh

#!/bin/bash

SHELL_NAME="shell_template_2.sh" SHELL_DIR="/home/oracle/scripts/shell" SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"

shell_log() {         LOG_INFO=$1         echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" ${SHELL_LOG} }

shell_usage() {         echo $"USAGE: $0 {backup}" }

mysql_backup() {         shell_log "mysql backup start"         shell_log "mysql backup stop" }

main() {         case $1 in                 backup)                         mysql_backup                         ;;                 *)

                        shell_usage;         esac }

main $1

shell_template_2.sh相比shell_template_1.sh,增加了如下,

  1. shell_usage()函数,用于说明脚本使用方法,即“shell_template_2.sh 跟着backup参数”。

  2. 主函数中则判断,若参数是backup,则执行mysql_backup(),否则执行shell_usage()函数,提示用户正确的使用方法。

错误的执行,

sh shell_template_2.sh USAGE: shell_template_2.sh {backup}

正确的执行,

sh shell_template_2.sh backup

日志显示,

vi shell_template_2.sh.log 2017-10-11 11-35-37 : shell_template_2.sh : mysql backup start 2017-10-11 11-35-37 : shell_template_2.sh : mysql backup stop

脚本三:避免多人同时执行脚本,需要增加锁机制,shell_template_3.sh

!/bin/bash

SHELL_NAME="shell_template_3.sh" SHELL_DIR="/home/oracle/scripts/shell" SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log" LOCK_FILE="/home/oracle/scripts/shell/${SHELL_NAME}.lock"

shell_log() {         LOG_INFO=$1         echo "$(date "+%Y-%m-%d") $(date "+%H-%M-%S") : ${SHELL_NAME} : ${LOG_INFO}" ${SHELL_LOG} }

shell_usage() {         echo $"USAGE: $0 {backup}" }

shell_lock() {         touch ${LOCK_FILE}

}

shell_unlock() {         rm -f ${LOCK_FILE} }

mysql_backup() {         if [ -f "${LOCK_FILE}" ]; then                 shell_log "${SHELL_NAME} is running"                 echo "${SHELL_NAME}" is running && exit         fi         shell_log "mysql backup start"         shell_lock         sleep 10         shell_log "mysql backup stop"         shell_unlock }

main() {         case $1 in                 backup)                         mysql_backup                         ;;                 *)                         shell_usage;         esac }

main $1

shell_template_3.sh相比shell_template_2.sh,增加了如下,

  1. 增加shell_lock()函数,用于touch一个文件,作为文件锁。
  1. 增加shell_unlock()函数,用于删除1创建的锁文件。

  2. mysql_backup()函数需要判断是否存在LOCK_FILE,若存在说明有用户正执行,此时提示信息,并退出程序,若不存在文件LOCK_FILE,则执行shell_lock创建锁文件,sleep 10秒,模拟执行,结束前执行shell_unlock,删除锁文件完成,此时其他用户可以执行。

用户A执行脚本,

sh shell_template_3.sh backup

sleep 10秒

用户B在10秒内,执行脚本,提示报错信息,并退出执行,

sh shell_template_3.sh backup; shell_template_3.sh is running

日志显示,

vi shell_template_3.sh.log

2017-10-11 11-42-03 : shell_template_3.sh : mysql backup start  --用户A记录

2017-10-11 11-42-08 : shell_template_3.sh : shell_template.sh is running  --用户B记录 2017-10-11 11-42-13 : shell_template_3.sh : mysql backup stop  --用户A记录

如果再做规范些,可以加上注释,

###################################################### # $Name:        shell_template.sh # $Version:     v1.0 # $Function:    Backup MySQL Databaes Template Script # $Author:      Bisal # $Create Date: 2017-10-11 # $Description: shell ######################################################

总结:

通过以上三个脚本,经历了“日志记录输出” - “增加脚本执行的方法说明,并通过传递参数,避免直接执行脚本的风险” - “利用文件锁,增加了锁机制,避免多人同时执行脚本,带来的可能风险”,这三个阶段,再加上注释,逐步完善,我们可以从中,汲取一些经验,

  1. 编写shell经常是面向过程的,但用函数封装,可以让脚本清晰可读。
  1. 通过文件锁机制,可以控制并发,其实这还有优化空间,有些场景应该允许用户并发,例如可以通过临时文件写入、合并操作的方法,实现用户并发。

  2. 标准常量定义、清晰的注释、函数和变量大小写用法,细节中可以看出严谨,即使只有几行,也能体现出,一名优秀工程师的素质。

虽然离这些目标还有距离,但通过这些优秀的脚本,吸取经验,增长见识,我们会朝着目标前进,兄弟们加油!

如果您觉得此篇文章对您有帮助,欢迎关注微信公众号:bisal的个人杂货铺,您的支持是对我最大的鼓励!共同学习,共同进步:)

经典的运维脚本三步曲 经典的运维脚本三步曲
本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> 经典的运维脚本三步曲


 上一篇
truncate表,会将统计信息清除么? truncate表,会将统计信息清除么?
看见微信群有位朋友问: truncate表,会将统计信息清除么? 有些朋友回复, 数据字典信息都没有了,统计信息就清除了,所以是没有统计信息的。做个实验,跟踪一下truncate,应该比较清楚。我做了10g的测试,发现那个表的las
下一篇 
探索索引的奥秘 – 索引的属性 探索索引的奥秘 – 索引的属性
索引是一种奇特的对象,他就像一把双刃剑,用好了可以提高性能,用不好就可能会影响性能,但如何才能用好索引? 可能我们日常工作中,同事、朋友,甚至我自己会问这种问题, 我们创建了索引,为什么这条SQL未用这索引?创建的索引越多,应