当我们需要监控服务运行状态时,一般的策略是写定时脚本,定时执行探测服务状态,如果出现预期外情况,就报警。那么第一步我们就需要学会写一个监控脚本,这里我们会讲到bash的执行环境和异常捕获,以及一些简单的全局参数。
示例先看一段shell代码,这个监控脚本会时刻监控我们的mysql进程是否正常服务,每2分钟执行一次:
#!/bin/bash#设置异常的捕获和退出set -eset -o pipefailset -u#获取当前脚本执行的命令和路径#self_name=`readlink -f $0`#self_path=`dirname $self_name`set +e# 脚本主体mysql_process_num=`ps aux | grep mysql | grep -v grep | grep -v bash | wc -l`set -e# 判断脚本输出,此处0为异常if [ "$mysql_process_num" -ge 1 ];then echo "$mysql_process_num|proc_name=mysql"else echo "0|proc_name=mysql"fi脚本命令解析执行器#!/bin/bash首行表示此脚本使用/bin/sh来解释执行,#!是特殊的标识符,后跟此脚本解释器的路径。类似的还有/bin/sh, /bin/perl, /bin/awk等。
我们在使用bash执行脚本的时候,会创建一个新的Shell,这个Shell就是脚本的执行环境,并默认提供这个环境的各个参数。
异常捕获set -eset -o pipefailset -uset +e我们的Shell会给脚本提供默认的环境参数,但是我们也可以用set命令来修改运行参数。在官方手册里一共有十几个参数,我们介绍常用的四个参数。
如果我们直接在终端运行set,不带任何参数,会显示所有的环境变量和Shell函数。
开启和关闭参数我们常见的类似传参形式的set -e代表打开e代表的环境参数,相反的set +e代表关闭e代表的环境参数。
捕获单行异常当我们遇到一个异常,如操作不存在的变量或者一行指令执行出错(行指令返回值不为0),Bash会默认输出错误信息,然后忽略这行错误,继续执行。这在大部分场景下并不是开发者想要的行为,也不利于脚本的安全和Debug。我们应该在错误出现的时候输出错误信息并中断执行。这样能够防止错误被累计和放大。
# 可执行文件run#!/bin/bash# 调用未定义的命令fooecho bar# 执行该文件$ ./run./run: line 3: foo: command not foundbar可以看到输出了错误信息,并继续执行。
如果我们想保证单行如果出现错误,就中断执行脚本,可以有三种写法:
# 方法一command || exit 1# 方法二if ! command; then exit 1; fi# 方法三commandif [ "$?" -ne 0 ]; then exit 1; fi上面的方法统一为判断一行指令返回值是否为0来判断异常。类似的,如果我们的多个命令有依赖关系,即后者的执行需要前者成功,则需要写:
...