编写Shell过程中注意事项
1 开头加解释器:#!/bin/bash
2 语法缩进,使用四个空格,多加注释说明
3 命名建议规则:变量名大写,局部变量小写,函数名小写,名字体现出实际作用。
4 默认变量是全局的,在函数中变量local指定为局部变量,避免污染其他作用域。
5 调试脚本命令:set -e 遇到执行非0时,退出脚本,set -x 打印执行过程。
6 写脚本一定先到测试环境,再到生产环境上。
1 获取随机字符串或数字
1)获取随机8位字符串:
方法1
]# echo $RANDOM | md5sum | cut -c 1-8
方法2
]# openssl rand -base64 4
方法3
]# cat /proc/sys/kernel/random/uuid | cut -c 1-8
2)获取随机8位数字
方法1
]# echo $RANDOM | cksum | cut -c 1-8 //cksum:打印CRC校验和统计字节
方法2
]# openssl rand -base64 4 | cksum | cut 1-8
方法3
]# date +%N | cut -c 1-8
2 定义一个颜色输出字符串函数
方法1
function echo_color() {
if [ $1 == "green" ];then
echo -e "\033[32;40m$2\033[0m"
elif [ $1 == "red" ]; then
echo -e "\033[32;40m$2\033[0m"
fi
}
方法2
function echo_color() {
case $1 in
green)
echo -e "[32;40m$2[0m"
;;
red)
echo -e "[32;40m$2[0m"
;;
*)
echo "Example:echo_color red string"
esac
}
3 批量创建用户
#! /bin/bash
DATE = $(date +%F_%T)
USER_FILE=user.txt
echo_color(){
if [ $1 == "green" ];then
echo -e "[32;40m$2[0m"
elif [ $1 == "red" ];then
echo -e "[32;40m$2[0m"
fi
}
#如果用户文件存在并大小大于0就备份
if [ -s $USER_FILE ]; then
mv $USER_FILE ${USER_FILE}-${DATE}.bak
echo_color green "$USER_FILE exist, rename ${USER_FILE}-${DATE}.bak"
fi
echo -e "User Password" >> $USER_FILE
echo "----------" >> $USER_FILE
for USER in user{1..10};do
if ! id $USER &>/dev/null; then
PASS=$(echo $RANDOM | md5sum | cut -c 1-8)
useradd $USER
echo $PASS | password --stdin $USER &> /dev/null
echo -e "$USER $PASS" >> $USER_FILE
echo "$USER User create successful"
fi
done
4 检查软件包是否安装
#!/bin/bash
if rpm -q sysstat &> /dev/null;then
echo "sysstat is already installed"
else
echo "sysstat is not installed"
fi
5 检查服务状态
#!/bin/bash
PORT_C = $(ss -anu | grep -c 123)
PS_C = $(ps -ef | grep ntpd | grep -vc grep)
if [ $PORT_C -eq 0 -o $PS_C -eq 0 ]; then
echo "内容" | mail -s "主题" [email protected]
fi
6 检查主机存活状态
方法1 : 将错误的IP放到数组里面,判断是否ping失败三次
#!/bin/bash
IP_LIST = "192.168.18.1 192.168.1.1 192.168.18.2"
for IP in $IP_LIST ;do
NUM = 1
while [ $NUM -le 3 ]; do
if ping -c 1 $IP > /dev/null; then
echo "$IP ping is successful."
break
else
# echo "$IP ping is failure $NUM"
FAIL_COUNT[$NUM]=$IP
let NUM++
fi
done
if [ ${#FAIL_COUNT[*]} -eq 3 ] ; then
echo "${FAIL_COUNT[1]} ping is failure"
unset FAIL_COUNT[*]
fi
done
方法2:将错误次数放到FAIL_COUNT变量里面判断是否ping失败三次
#!/bin/bash
IP_LIST = "192.168.18.1 192.168.1.1 192.168.28.2"
for IP in $IP_LIST ; do
FAIL_COUNT=0
for ((i=1;i<=3;i++));do
if ping -c 1 $IP > /dev/null; then
echo "$IP ping is successful"
break
else
# echo "$IP ping is failure $i"
let FAIL_ COUNT++
fi
done
if [ $FAIL_COUNT -eq 3 ]; then
echo "$IP ping is failure"
fi
done
方法3 :利用for循环将ping通就跳出循环继续,如果不跳出就会打印ping失败。
#!/bin/bash
ping_success_status() {
if ping -c 1 $IP > /dev/null; then
echo "$IP ping is successful"
continue
fi
}
IP_LIST = "192.168.18.1 192.168.1.1 192.168.18.2"
for IP in $IP_LIST ; do
ping_success_status
ping_success_status
ping_success_status
echo "$IP ping is failure"
done
7 监控CPU、内存和硬盘利用率
1)CPU
借助vmstat 工具来分析CPU统计信息
#!/bin/bash
DATE=$(date +%H:%M)
IP=$(ifconfig eth0 | awk -F [ : ]+ /inet addr/{print $4}) # 只支持Centos6
MAIL="[email protected]"
if ! which vmstat &> /dev/null; then
echo "vmstat command no found , Please install procps package"
exit 1
fi
US = $(vmstat | awk NR==3{print $13})
SY = $(vmstat | awk NR==3{print $14})
IDLE = $(vmstat | awk NR==3{print $15})
WAIT = $(vmstat | awk NR==3{print $16})
USE = $(($US+$UY))
if [ $USE -ge 50 ];then
echo "
Date: $DATE
Host: $IP
Problem: CPU utilization $USE
" | mail -s "CPU Monitor" $MAIL
fi
内存
#!/bin/bash
DATE = $(date +%F""%H:%M)
IP = $(ifconfig eth0 | awk -F [ : ]+ /inet addr/{print $4} )
MAIL = "[email protected]"
TOTAL = $(free -m | awk /Mem/{print $2} )
USE = $(free -m | awk /Mem/{print $3-$6-$7} )
FREE = $(($TOTAL-$USE))
# 内存小于1G,发送报警邮件
if [ $FREE -lt 1024 ]; then
echo "
Date : $DATE
Host : $IP
Problem : Total=$TOTAL,Use=$USE,Free=$FREE
" | mail -s "Memory Monitor" $MAIL
if
3)硬盘
#!/bin/bash
DATE = $(date +%F" "%H:%M)
IP = $(ifconfig eth0 | awk -F [ : ]+ /inet addr/{print $4})
MAIL = "[email protected]"
TOTAL = $(fdisk -l | awk -F [ : ]+ BEGIN{OFS="="}/^Disk /dev/{printf "%s=%sG,",$2,$3})
PART_USE = $(df -h | awk BEGIN{OFS="="}/^/dev/{print $1,int($5),$6})
for i in $PART_USE; do
PART = $(echo $i | cut -d "=" -f1)
USE = $(echo $i | cut -d "=" -f2)
MOUNT = $(echo $i | cut -d "=" -f3)
if [ $USE -gt 80 ]; then
echo "
Date : $DATE
Host : $IP
Total : $TOTAL
Problem : $PART=$USE($MOUNT)
" | mail -s "Disk Monitor" $MAIL
fi
done
8 批量主机磁盘利用率监控
前提监控端和被监控端SSH免交互登录或者密钥登录
写一个配置文件保存被监控主机SSH连接信息,文件内容格式: IP User Port
#!/bin/bash
HOST_INFO = host.info
for IP in $(awk /^[^#]/{print $1} $HOST_INFO); do
USER = $(awk -v ip=$IP ip==$1{print $2} $HOST_INFO)
PORT = $(awk -v ip=$IP ip==$1{print $3} $HOST_INTO)
TMP_FILE=/tmp/disk.tmp
ssh -p $PORT $USER@$IP df -h > $TMP_FILE
USE_RATE_LIST = $(awk BEGIN{OFS= "="}/^/dev/{print $1,int($5)} $TMP_FILE)
for USE_RATE in $USE_RATE_LIST; do
PART_NAME = ${USE_RATE%=*}
USE_RATE = ${USE_RATE#*=}
if [ $USE_RATE -ge 80 ]; then
echo "Warning: $ PART_NAME Partition usage $USE_RATE%!"
fi
done
done
9 检查网站可用性
1)检查URL可用性
方法1
check_url() {
HTTP_CODE = $(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $1)
if [ $HTTP_CODE -ne 200 ]; then
echo "Warning: $1 Access failure"
fi
}
方法2
check_url(){
if ! wget -T 10 --tries=1 --spider $1 >/dev/null 2>&1; then
#-T 超时时间,--tries尝试1次,--spider爬虫模式
echo "Warnin : $1 Access failure"
fi
}
2)判断三次URL可用性
方法1:利用循环技巧,如果成功就跳出当前循环,否则执行都最后一行
#!/bin/bash
check_url(){
HTTP_CODE = $(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $1)
if [ $HTTP_CODE -eq 200 ]; then
continue
fi
}
URL_LIST = "www.baidu.com www.runoob.com"
for URL in $URL_LIST; do
check_url $URL
check_url $URL
check_url $URL
echo "Warning : $URL Access failure"
done
方法2:错误次数保存到变量
#!/bin/bash
URL_LIST = "www.baidu.com www.runoob.com"
for URL in $URL_LIST; do
FAIL_COUNT = 0
for ((i=1;i<=3;i++)); do
HTTP_CODE = $(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $URL)
if [ $HTTP_CODE -ne 200 ]; then
let FAIL_CONUT++
else
break
fi
done
if [ $FAIL_COUNT -eq 3 ]; then
echo "Warning : $URL Access failure"
if
done
方法3:错误次数保存到数组
#!/bin/bash
URL_LIST = "www.baidu.com www.runoob.com"
for URL in $URL_LIST ; do
NUM = 1
while [ $NUM -le 3 ] ; do
HTTP_CODE= $(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $URL)
if [ $HTTP_CODE -ne 200 ]; then
FAIL_COUNT[$NUM]=$IP #创建数组,以$NUM下标,$IP元素
let NUM++
else
break
fi
done
if [ ${#FAIL_COUNT[*]} -eq 3]; then
echo "Warning : $URL Access failure"
unset FAIL_COUNT[*] #清空数组
if
done
10 检查MySQL主从同步状态
#!/bin/bash
USER=bak
PASSWD=123456
IO_SQL_STATUS= ( m y s q l − u (mysql -u (mysql−uUSER -p$PASSWD -e show slave status/G | awk -F: /Slave_._Running/{gsub(": “,”?;print $0} ) #gsub去除冒号后面的空格
for i in I O S Q L S T A T U S ; d o T H R E A D S T A T U S N A M E = IO_SQL_STATUS ;do THREAD_STATUS_NAME= IOSQLSTATUS;doTHREADSTATUSNAME={i%:}
THREAD_STATUS=KaTeX parse error: Expected '}', got '#' at position 3: {i#̲*:} if [ "THREAD_STATUS" != “Yes” ]; then
echo “Error: MySQL Master-Slave $THREAD_STATUS_NAME status is $THREAD_STATUS!”
if
done
参考:原文地址