The classic three-step operation and maintenance script

Whether it is application operation and maintenance or database operation and maintenance, it can be divided into "human flesh" - "automation" - "intelligence" stage. The automation stage is mainly to encapsulate the operations done by some people, especially some repetitive operations For the program, on the one hand, it avoids repetitive operations, and on the other hand, it improves the execution efficiency. In the process of automation implementation, shell scripts are often used. Some time ago, from a WeChat public account, I learned a small article written by Squad Leader Zhao, and introduced the writing of shell operation and maintenance scripts in a step-by-step manner. The script has great wisdom, dozens of lines of code, mixed with details such as system design and code specification, and it is worth learning.


The following script refers to the original text: " How to do operation and maintenance without being a rogue-SHELL script ", using shell script to simulate the mysql backup process, three scripts step by step.


Script 1: shell script for logging, 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"


The function responsible for printing the log, shell_log(), accepts the first parameter as the log content to be printed. The format of the log output is defined in shell_log() (year-month-day-hour-minute-second: script name: log content ), the log file path is defined by the $SHELL_LOG variable.


Execute shell_template_1.sh to generate the log file 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




Script 2 : Directly executed scripts are very dangerous. To prompt the user how to use the script, 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一个文件,作为文件锁。

2. 增加shell_unlock()函数,用于删除1创建的锁文件。

3. 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经常是面向过程的,但用函数封装,可以让脚本清晰可读。

2. 通过文件锁机制,可以控制并发,其实这还有优化空间,有些场景应该允许用户并发,例如可以通过临时文件写入、合并操作的方法,实现用户并发。

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


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


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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325599673&siteId=291194637