运维实用脚本整理

news2024/11/27 8:25:39

运维实用脚本整理

  • Linux运维日常巡检脚本
  • 系统指标巡检脚本
  • 日常命令
    • 性能相关的命令
    • 进程相关的命令
    • javadump.sh
  • 常用工具一键部署安装
  • 常用lib库安装
  • 系统检查脚本
  • SPN 日常巡查脚本
  • ffmpeg脚本
    • 打开进程,并判断进程数量
    • 关闭进程
  • java jar包启动-剔除Pom中依赖
  • Java jar包通用启动脚本
  • 查看centos配置信息脚本
  • Jenkins项目打包发布脚本
  • Mysql-使用脚本进行分库分表备份
  • 监控某个目录是否被更改
    • 确保本机能连上shell脚本中指定的smtp服务器的25好端口
    • 下面开始测试
    • 查看邮件,就能看到/data/test目录下变动的文件或子目录信息了
    • 通过crontab定时任务,每5分钟执行一次检查:
  • 日志文件ERROR监控报警
    • 1)第一类日志
    • 2)第二类日志
    • 3)第三类日志
  • 基于Ping和Telnet/NC的监控脚本案例分析
    • 通过shell脚本,判断172.16.60.0/24网络里,当前在线的ip有哪些?能ping通则认为在线。
      • 案例一:单纯地对某些ip进行ping监控
      • 案例二:对/etc/hosts列表里的ip映射关系进行ping监控报警
      • 案例三:通过nc工具对/etc/hosts列表里的ip的443端口跟本机通信是否正常进行探测
  • 监控磁盘的监控脚本
    • 监控磁盘IO使用率的脚本,实时查看IO使用情况,防止因为磁盘IO效率低而导致MySQL查询慢的问题
  • 实时监控网卡流量的通用脚本
  • 检测网卡流量,并按规定格式记录在日志中
  • 指定时间内网站访问次数的监控
    • nginx日志监控脚本
    • python报警脚本
    • 写个测试脚本不停curl请求资源触发报警
    • 定时任务,由于上面脚本是监控一分钟内的日志,因此每分钟执行一次
  • 网站访问状态和超时时间监控报警设置
  • 服务器磁盘监控脚本(含报警邮件)
  • 业务日志清理脚本
  • Linux下间隔多少秒 (即以秒为单位) 去执行某条命令或某个shell脚本的操作方法
  • Linux下批量ping某个网段ip的脚本
  • 查看系统运行情况
  • 管理docker
  • Shell多线程备份数据库
  • 监测 Nginx 访问日志 502 情况,并做相应动作
  • 检测两台服务器指定目录下的文件一致性
  • 定时清空文件内容,定时记录文件大小
  • 计算文档每行出现的数字个数,并计算整个文档的数字总数
  • 杀死所有脚本
  • 从 FTP 服务器下载文件
  • 扫描主机端口状态
  • 监控 httpd 的进程数,根据监控情况做相应处理
  • iptables 自动屏蔽访问网站频繁的IP
    • 1)屏蔽每分钟访问超过200的IP
    • 2)屏蔽每分钟SSH尝试登录超过10次的IP
  • 根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁
  • 判断用户输入的是否为IP地址

Linux运维日常巡检脚本

#!/bin/bash
#author by acrossyao
#date: 2021-02-08
#巡检脚本
echo "---------------------------------------「OS系统巡检信息」---------------------------------------"
#OS_IP=`hostname -i | awk '{print $1}'`
OS_IP=""
IPLIST=`hostname -i`
for elem in $IPLIST
do
regex="\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\b"
ckStep2=`echo $elem | egrep $regex | wc -l`
if [ $ckStep2 -eq 0 ]
then
aa=1
else
OS_IP+=$elem", "
fi
done
OS_HOSTNAME=`hostname`
OS_RUN_TIME=`uptime |awk '{print $3,$4}'|awk -F, '{print $1}'`
echo " 系统IP地址: $OS_IP"
echo " 主机名称: $OS_HOSTNAME"
echo " 运行时间: $OS_RUN_TIME"
#内存
OS_MEM_TAL=`free -m | grep Mem | awk '{print $2}'`
OS_MEM_FREE=`free -m | grep Mem | awk '{print $7}'`
echo " 内存总量: ${OS_MEM_TAL}MB"
echo " 内存余量: ${OS_MEM_FREE}MB"
#磁盘使用占比
OS_ROOT_DISKS_USE_PRECENT=`df -h / | grep '/'| awk '{print $5}'`
OS_ROOT_DISKS_AVAIL=`df -h / | grep '/'| awk '{print $4}'`
OS_DATA_DISKS_USE_PRECENT=`df -h | grep '/data'| awk '{print $5}'`
OS_DATA_DISKS_AVAIL=`df -h | grep '/data'| awk '{print $4}'`
echo " 根卷使用占比: ${OS_ROOT_DISKS_USE_PRECENT}, 根卷空闲: ${OS_ROOT_DISKS_AVAIL}"
echo " data卷使用占比: ${OS_DATA_DISKS_USE_PRECENT}, data卷空闲: ${OS_DATA_DISKS_AVAIL}"
#CPU
CPU_LOAD=`top -bn1 | grep load | awk '{printf "CPU LOAD: %.2f\n", $(NF-2)}'`
CPU_IDLE=`top -n1 | fgrep "Cpu(s)" | awk -F ',' '{print $4}'`
echo " ${CPU_LOAD}"
echo " CPU IDLE: ${CPU_IDLE}"
echo "---------------------------------------「OS系统巡检结束」---------------------------------------"

在这里插入图片描述

系统指标巡检脚本

#!/bin/bash
menu(){
cat <<EOF
+---------------------------------------------+
|        日常巡检脚本                  |
|        1.查看磁盘使用率              |    
|        2.查看内存使用率              |
|        3.查看系统负载                |
|        4.统计系统连接数              |
|        5.统计系统进程数              |
|        6.统计当前磁盘分区信息        |
|        7.按q退出                     |
|        8.按h帮助                     |
+---------------------------------------------+
EOF
}
menu
while true
do
echo -en "\033[34m请输入你要查看的内容:\033[0m"
read  action
    if [ "$action" == "q" ];then
        echo "quiting...."
        break
    fi
    if [ "$action" == "h" ];then
        menu
    fi
    case $action in 
    1)
        df -h ;;
    2)
        free -h ;;
    3)
        uptime ;;
    4)
        ss -tan | grep -i "estab" | wc -l ;;
    5)
        ps aux | grep -v "grep" | wc -l ;;
    6)
        fdisk -l ;;        
    *)
        echo "Usage: $0 {1|2|3|4|5|6|q|h}"
    esac
done

在这里插入图片描述

日常命令

1、查找当前目录下占用为0字节的文件并删除

find ./ -type f -size 0 -exec rm -rf {}\;    #此命令不要用于对根目录0字节文件的操作

2、将系统进程按内存占用大小排列显示出来

ps -e  -o “%C   : %p : %z : %a”|sort -k5-nr   

3、将系统进程按CPU占用大小排列显示

ps -e  -o “%C   : %p : %z : %a”|sort   -nr

4、匹配某文件中某一行并进行内容替换

sed -i ‘/Root/s/no/yes’/etc/ssh/sshd_config    #先匹配到Root,再将此行no替换为yes

5、显示所有运行级别为3并开机启动的服务

ls /etc/rc3.d/S* |cut -c 15-    #rc3.d中S开头即为运行级别3的服务,并用cut截取第15个字符后面的内容

6、取得eth0网卡的IP地址 

方法1:ifconfig   | grep ‘inet addr:| grep -v ’127.0.0.1| cut -d:-f2 | awk ‘{ print $1}’

方法2:ifconfig eth0 |grep “inet addr:|awk ‘{print $2}|cut -c 6-

7、TCP抓包工具分析80端口数据流

tcpdump -c 10000 -i eth0 -n dst port 80

8、查询昨天的日期

date –date=yesterday

9、删除所有空目录

find /data -type d -empty -exec rm -rf {};    #最好不要在/目录下执行此命令

10、删除5天前的文件

find /data -mtime +5 -type f -exec rm -rf{};

11、强制踢出终端用户

pkill -KILL -t pts/1

12、将来自80端口的请求转发到8080端口

iptables -A PREROUTING -p tcp -m tcp –dport80 -j DNAT –to-destination 127.0.0.1:8080

13Linux服务器之间传文件

scp ~/test.txtroot@192.168.0.10:/data/    #将个人主目录下test.txt传到远程主机的/data目录下

14、对大文件进行分割

split -l 1000 message.log message    #按每个文件1000行来分割

split -b 5m message.log message    #按每个文件5M来分割

性能相关的命令

#查看当前系统load
uptime

#查看系统状态和每个进程的系统资源使用状况
top

#可视化显示CPU的使用状况
htop

#查看每个CPU的负载信息
mpstat -P ALL 1

#每隔1秒查看磁盘IO的统计信息
iostat -xkdz 1

#每隔一秒查看虚拟内存的使用信息
vmstat 1

#查看内存使用统计信息
free

#查看网络使用信息
nicstat -z 1

#类似vmstat的显示优化的工具
dstat 1

#查看系统活动状态,比如系统分页统计,块设备IO统计等
sar

#网络连接状态查看
netstat -s

#进程资源使用信息查看
pidstat 1
pidstat -d 1

#查看某个进程的系统调用信息 -p后面是进程id,-tttT 进程系统后的系统调用时间
strace -tttT -p 12670
#统计IO设备输入输出的系统调用信息
strace -c dd if=/dev/zero of=/dev/null bs=512 count=1024k


#tcpdump 查看网络数据包
tcpdump -nr /tmp/out.tcpdump

#块设备的读写事件信息统计
btrace /dev/sdb 

#iotop查看某个进程的IO操作统计信息
iotop -bod5

#slabtop 查看内核 slab内存分配器的使用信息
slabtop -sc

#系统参数设置
sysctl -a

#系统性能指标统计信息
perf stat gzip file1

#系统cpu活动状态查看
perf record -a -g -F 997 sleep 10

进程相关的命令

## processes  进程管理

##ps查看当前系统执行的线程列表,进行瞬间状态,不是连续状态,连续状态需要使用top名称查看  更多常用参数请使用 man ps查看
ps

##显示所有进程详细信息
ps aux

##-u 显示某个用户的进程列表
ps -f -u www-data 

## -C 通过名字或者命令搜索进程
ps -C apache2

## --sort  根据进程cpu使用率降序排列,查看前5个进程  -pcpu表示降序  pcpu升序
ps aux --sort=-pcpu | head -5 

##-f 用树结构显示进程的层次关系,父子进程情况下
ps -f --forest -C apache2 

##显示一个父进程的所有子进程
ps -o pid,uname,comm -C apache2
ps --ppid 2359 

##显示一个进程的所有线程  -L 参数
ps -p 3150 -L 

##显示进程的执行时间 -o参数
ps -e -o pid,comm,etime 

##watch命令可以用来实时捕捉ps显示进程
watch -n 1 'ps -e -o pid,uname,cmd,pmem,pcpu --sort=-pmem,-pcpu | head -15' 

##jobs 查看后台运行的进程  jobs命令执行的结果,+表示是一个当前的作业,减号表是是一个当前作业之后的一个作业,jobs -l选项可显示所有任务的PID,jobs的状态可以是running, stopped, Terminated,但是如果任务被终止了(kill),shell 从当前的shell环境已知的列表中删除任务的进程标识;也就是说,jobs命令显示的是当前shell环境中所起的后台正在运行或者被挂起的任务信息
jobs

##查看后台运营的进程号
jobs -p

##查看现在被终止或者退出的进程号
jobs -n


##kill命令 终止一个前台进程可以使用Ctrl+C键   kill  通过top或者ps获取进程id号  kill [-s 信号 | -p ] [ -a ] 进程号 ...
##发送指定的信号到相应进程。不指定型号将发送SIGTERM(15)终止指定进程。关闭进程号12的进程
kill 12


##等同于在前台运行PID为123的进程时按下Ctrl+C键
kill -2 123

##如果任无法终止该程序可用“-KILL” 参数,其发送的信号为SIGKILL(9) ,将强制结束进程  
kill -9 123

##列出所有信号名称
##HUP    1    终端断线
##INT     2    中断(同 Ctrl + C)
##QUIT    3    退出(同 Ctrl + \)
##TERM   15    终止
##KILL    9    强制终止
##CONT   18    继续(与STOP相反, fg/bg命令)
##STOP    19    暂停(同 Ctrl + Z)
kill -l

##得到指定信号的数值
kill -l KILL

##杀死指定用户所有进程
kill -u peidalinux
kill -9 $(ps -ef | grep peidalinux) 

##将后台中的命令调至前台继续运行  将进程123调至前台执行
fg 123

##将一个在后台暂停的命令,变成继续执行
bg  123

##该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。nohup就是不挂起的意思  下面输出被重定向到myout.file文件中
nohup command > myout.file 2>&1 &

##at:计划任务,在特定的时间执行某项工作,在特定的时间执行一次。
## 格式:at HH:MM YYYY-MM-DD //HH(小时):MM(分钟) YYYY(年)-MM(月份)-DD(日)
##HH[am pm]+D() days //HH(小时)[am(上午)pm(下午)]+days(天)
at 12:00(时间) //at命令设定12:00执行一项操作
#at>useradd aaa //在at命令里设定添加用户aaa
#ctrl+d //退出at命令
#tail -f /etc/passwd //查看/etc/passwd文件后十行是否增加了一个用户aaa

##计划任务设定后,在没有执行之前我们可以用atq命令来查看系统没有执行工作任务。
atq

##启动计划任务后,如果不想启动设定好的计划任务可以使用atrm命令删除。
atrm 1 //删除计划任务1

##pstree命令:列出当前的进程,以及它们的树状结构  格式:pstree [选项] [pid|user]
pstree

##nice命令:改变程序执行的优先权等级 应用程序优先权值的范围从-2019,数字越小,优先权就越高。一般情况下,普通应用程序的优先权值(CPU使用权值)都是0,如果让常用程序拥有较高的优先权等级,自然启动和运行速度都会快些。需要注意的是普通用户只能在019之间调整应用程序的优先权值,只有超级用户有权调整更高的优先权值(从-2019)。
nice [-n <优先等级>][--help][--version][命令]
nice -n 5 ls

##sleep命令:使进程暂停执行一段时间
date;sleep 1m;date


##renice命令 renice命令允许用户修改一个正在运行进程的优先权。利用renice命令可以在命令执行时调整其优先权。
##其中,参数number与nice命令的number意义相同。(1) 用户只能对自己所有的进程使用renice命令。(2) root用户可以在任何进程上使用renice命令。(3) 只有root用户才能提高进程的优先权
renice -5 -p 5200  #PID为5200的进程nice设为-5 

##pmap命令用于显示一个或多个进程的内存状态。其报告进程的地址空间和内存状态信息 #pmap PID 
pmap 20367

javadump.sh

#!/bin/sh

DUMP_PIDS=`ps  --no-heading -C java -f --width 1000 |awk '{print $2}'`
if [ -z "$DUMP_PIDS" ]; then
    echo "The server $HOST_NAME is not started!"
    exit 1;
fi

DUMP_ROOT=~/dump
if [ ! -d $DUMP_ROOT ]; then
  mkdir $DUMP_ROOT
fi

DUMP_DATE=`date +%Y%m%d%H%M%S`
DUMP_DIR=$DUMP_ROOT/dump-$DUMP_DATE
if [ ! -d $DUMP_DIR ]; then
  mkdir $DUMP_DIR
fi

for PID in $DUMP_PIDS ; do
#Full thread dump 用来查线程占用,死锁等问题
  $JAVA_HOME/bin/jstack $PID > $DUMP_DIR/jstack-$PID.dump 2>&1
  echo -e ".\c"
#打印出一个给定的Java进程、Java core文件或远程Debug服务器的Java配置信息,具体包括Java系统属性和JVM命令行参数。
  $JAVA_HOME/bin/jinfo $PID > $DUMP_DIR/jinfo-$PID.dump 2>&1
  echo -e ".\c"
#jstat能够动态打印jvm(Java Virtual Machine Statistics Monitoring Tool)的相关统计信息。如young gc执行的次数、full gc执行的次数,各个内存分区的空间大小和可使用量等信息。
  $JAVA_HOME/bin/jstat -gcutil $PID > $DUMP_DIR/jstat-gcutil-$PID.dump 2>&1
  echo -e ".\c"
  $JAVA_HOME/bin/jstat -gccapacity $PID > $DUMP_DIR/jstat-gccapacity-$PID.dump 2>&1
  echo -e ".\c"
#未指定选项时,jmap打印共享对象的映射。对每个目标VM加载的共享对象,其起始地址、映射大小及共享对象文件的完整路径将被打印出来,  
  $JAVA_HOME/bin/jmap $PID > $DUMP_DIR/jmap-$PID.dump 2>&1
  echo -e ".\c"
#-heap打印堆情况的概要信息,包括堆配置,各堆空间的容量、已使用和空闲情况  
  $JAVA_HOME/bin/jmap -heap $PID > $DUMP_DIR/jmap-heap-$PID.dump 2>&1
  echo -e ".\c"
#-dump将jvm的堆中内存信息输出到一个文件中,然后可以通过eclipse memory analyzer进行分析
#注意:这个jmap使用的时候jvm是处在假死状态的,只能在服务瘫痪的时候为了解决问题来使用,否则会造成服务中断。
  $JAVA_HOME/bin/jmap -dump:format=b,file=$DUMP_DIR/jmap-dump-$PID.dump $PID 2>&1
  echo -e ".\c"
#显示被进程打开的文件信息
if [ -r /usr/sbin/lsof ]; then
  /usr/sbin/lsof -p $PID > $DUMP_DIR/lsof-$PID.dump
  echo -e ".\c"
  fi
done
#主要负责收集、汇报与存储系统运行信息的。
if [ -r /usr/bin/sar ]; then
  /usr/bin/sar > $DUMP_DIR/sar.dump
echo -e ".\c"
fi
#主要负责收集、汇报与存储系统运行信息的。
if [ -r /usr/bin/uptime ]; then
  /usr/bin/uptime > $DUMP_DIR/uptime.dump
echo -e ".\c"
fi
#内存查看
if [ -r /usr/bin/free ]; then
  /usr/bin/free -t > $DUMP_DIR/free.dump
echo -e ".\c"
fi
#可以得到关于进程、内存、内存分页、堵塞IO、traps及CPU活动的信息。
if [ -r /usr/bin/vmstat ]; then
  /usr/bin/vmstat > $DUMP_DIR/vmstat.dump
echo -e ".\c"
fi
#报告与CPU相关的一些统计信息
if [ -r /usr/bin/mpstat ]; then
  /usr/bin/mpstat > $DUMP_DIR/mpstat.dump
echo -e ".\c"
fi
#报告与IO相关的一些统计信息
if [ -r /usr/bin/iostat ]; then
  /usr/bin/iostat > $DUMP_DIR/iostat.dump
echo -e ".\c"
fi
#报告与网络相关的一些统计信息
if [ -r /bin/netstat ]; then
  /bin/netstat > $DUMP_DIR/netstat.dump
echo -e ".\c"
fi
echo "OK!"

常用工具一键部署安装

#!/usr/bin/env bash

# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------

printf "${BLUE}\n"
cat << EOF
###################################################################################
# 安装常用命令工具
# 命令工具清单如下:
# 核心工具:df、du、chkconfig
# 网络工具:ifconfig、netstat、route、iptables
# IP工具:ip、ss、ping、tracepath、traceroute
# DNS工具:dig、host、nslookup、whois
# 端口工具:lsof、nc、telnet
# 下载工具:curl、wget
# 编辑工具:emacs、vim
# 流量工具:iftop、nethogs
# 抓包工具:tcpdump
# 压缩工具:unzip、zip
# 版本控制工具:git、subversion
#
###################################################################################
EOF
printf "${RESET}\n"

printf "\n${GREEN}>>>>>>>>> 安装常用命令工具开始${RESET}\n"

# 核心工具
printf "\n${CYAN}>>>> install coreutils(df、du)${RESET}\n"
yum install -y coreutils
printf "\n${CYAN}>>>> install chkconfig${RESET}\n"
yum install -y chkconfig

# 网络工具
printf "\n${CYAN}>>>> install net-tools(ifconfig、netstat、route)${RESET}\n"
yum install -y net-tools
printf "\n${CYAN}>>>> install iptables${RESET}\n"
yum install -y iptables

# IP工具
printf "\n${CYAN}>>>> install iputils(ping、tracepath)${RESET}\n"
yum install -y iputils
printf "\n${CYAN}>>>> install traceroute${RESET}\n"
yum install -y traceroute
printf "\n${CYAN}>>>> install iproute(ip、ss)${RESET}\n"
yum install -y iproute

# 端口工具
printf "\n${CYAN}>>>> install lsof${RESET}\n"
yum install -y lsof
printf "\n${CYAN}>>>> install nc${RESET}\n"
yum install -y nc
printf "\n${CYAN}>>>> install netstat${RESET}\n"
yum install -y netstat

# DNS工具
printf "\n${CYAN}>>>> install bind-utils(dig、host、nslookup)${RESET}\n"
yum install -y bind-utils
printf "\n${CYAN}>>>> install whois${RESET}\n"
yum install -y whois

# 下载工具
printf "\n${CYAN}>>>> install curl${RESET}\n"
yum install -y curl
printf "\n${CYAN}>>>> install wget${RESET}\n"
yum install -y wget

# 编辑工具
printf "\n${CYAN}>>>> install emacs${RESET}\n"
yum install -y emacs
printf "\n${CYAN}>>>> install vim${RESET}\n"
yum install -y vim

# 流量工具
printf "\n${CYAN}>>>> install iftop${RESET}\n"
yum install -y iftop
printf "\n${CYAN}>>>> install nethogs${RESET}\n"
yum install -y nethogs

# 抓包工具
printf "\n${CYAN}>>>> install tcpdump${RESET}\n"
yum install -y tcpdump

# 压缩工具
printf "\n${CYAN}>>>> install unzip${RESET}\n"
yum install -y unzip

# 版本控制工具
printf "\n${CYAN}>>>> install git${RESET}\n"
yum install -y git
printf "\n${CYAN}>>>> install subversion${RESET}\n"
yum install -y subversion

printf "\n${GREEN}<<<<<<<< 安装常用命令工具结束${RESET}\n"

常用lib库安装

lib库分为两种,一种是静态链接lib库或者叫做静态lib库,另一种叫做动态链接库dll库的lib导入库或称为lib导入库。

第一种是静态lib,包含了所有的代码实现的,是源代码文件.c或.cpp文件编译生成的,这个lib库就是文本形式的源代码编译后的二进制形式代码。

第二种就是lib导入库,这个库只是dll文件中的所有函数在dll文件中的地址的说明。

#!/usr/bin/env bash

# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------

printf "${BLUE}\n"
cat << EOF
###################################################################################
# 安装常见 lib
# 如果不知道命令在哪个 lib,可以使用 yum search xxx 来查找
# lib 清单如下:
# gcc gcc-c++ kernel-devel libtool
# openssl openssl-devel
# zlib zlib-devel
# pcre
###################################################################################
EOF
printf "${RESET}\n"

printf "\n${GREEN}>>>>>>>>> 安装常见 lib 开始${RESET}\n"

printf "\n${CYAN}>>>> install gcc gcc-c++ kernel-devel libtool${RESET}\n"
yum -y install make gcc gcc-c++ kernel-devel libtool

printf "\n${CYAN}>>>> install openssl openssl-devel${RESET}\n"
yum -y install make openssl openssl-devel

printf "\n${CYAN}>>>> install zlib zlib-devel${RESET}\n"
yum -y install make zlib zlib-devel

printf "\n${CYAN}>>>> install pcre${RESET}\n"
yum -y install pcre

printf "\n${GREEN}<<<<<<<< 安装常见 lib 结束${RESET}\n"

系统检查脚本

#!/usr/bin/env bash

##############################################################################
# console color
C_RESET="$(tput sgr0)"
C_BLACK="\033[1;30m"
C_RED="\033[1;31m"
C_GREEN="\033[1;32m"
C_YELLOW="\033[1;33m"
C_BLUE="\033[1;34m"
C_PURPLE="\033[1;35m"
C_CYAN="\033[1;36m"
C_WHITE="\033[1;37m"
##############################################################################

printf "${C_PURPLE}"
cat << EOF
###################################################################################
# 系统信息检查脚本
###################################################################################
EOF
printf "${C_RESET}"

[[ $(id -u) -gt 0 ]] && echo "请用root用户执行此脚本!" && exit 1
sysversion=$(rpm -q centos-release | cut -d- -f3)
double_line="==============================================================="
line="----------------------------------------------"

# 打印头部信息
printHeadInfo() {
  cat << EOF
+---------------------------------------------------------------------------------+
|                           欢迎使用 【系统信息检查脚本】                          |
+---------------------------------------------------------------------------------+
EOF
}

# 打印尾部信息
printFootInfo() {
  cat << EOF
+---------------------------------------------------------------------------------+
|                            脚本执行结束,感谢使用!|
+---------------------------------------------------------------------------------+
EOF
}

options=( "获取系统信息" "获取服务信息" "获取CPU信息" "获取系统网络信息" "获取系统内存信息" "获取系统磁盘信息" "获取CPU/内存占用TOP10" "获取系统用户信息" "输出所有信息" "退出" )
printMenu() {
  printf "${C_BLUE}"
  printf "主菜单:\n"
  for i in "${!options[@]}"; do
    index=`expr ${i} + 1`
    val=`expr ${index} % 2`
    printf "\t(%02d) %-30s" "${index}" "${options[$i]}"
    if [[ ${val} -eq 0 ]]; then
      printf "\n"
    fi
  done
  printf "${C_BLUE}请输入需要执行的指令:\n"
  printf "${C_RESET}"
}

# 获取系统信息
get_systatus_info() {
  sys_os=$(uname -o)
  sys_release=$(cat /etc/redhat-release)
  sys_kernel=$(uname -r)
  sys_hostname=$(hostname)
  sys_selinux=$(getenforce)
  sys_lang=$(echo $LANG)
  sys_lastreboot=$(who -b | awk '{print $3,$4}')
  sys_runtime=$(uptime | awk '{print  $3,$4}' | cut -d, -f1)
  sys_time=$(date)
  sys_load=$(uptime | cut -d: -f5)

  cat << EOF
【系统信息】
系统: ${sys_os}
发行版本:   ${sys_release}
系统内核:   ${sys_kernel}
主机名:    ${sys_hostname}
selinux状态:  ${sys_selinux}
系统语言:   ${sys_lang}
系统当前时间: ${sys_time}
系统最后重启时间:   ${sys_lastreboot}
系统运行时间: ${sys_runtime}
系统负载:   ${sys_load}
EOF
}

# 获取CPU信息
get_cpu_info() {
  Physical_CPUs=$(grep "physical id" /proc/cpuinfo | sort | uniq | wc -l)
  Virt_CPUs=$(grep "processor" /proc/cpuinfo | wc -l)
  CPU_Kernels=$(grep "cores" /proc/cpuinfo | uniq | awk -F ': ' '{print $2}')
  CPU_Type=$(grep "model name" /proc/cpuinfo | awk -F ': ' '{print $2}' | sort | uniq)
  CPU_Arch=$(uname -m)
  cat << EOF
【CPU信息】
物理CPU个数:$Physical_CPUs
逻辑CPU个数:$Virt_CPUs
每CPU核心数:$CPU_Kernels
CPU型号:$CPU_Type
CPU架构:$CPU_Arch
EOF
}

# 获取服务信息
get_service_info() {
  port_listen=$(netstat -lntup | grep -v "Active Internet")
  kernel_config=$(sysctl -p 2> /dev/null)
  if [[ ${sysversion} -gt 6 ]]; then
    service_config=$(systemctl list-unit-files --type=service --state=enabled | grep "enabled")
    run_service=$(systemctl list-units --type=service --state=running | grep ".service")
  else
    service_config=$(/sbin/chkconfig | grep -E ":on|:启用" | column -t)
    run_service=$(/sbin/service --status-all | grep -E "running")
  fi
  cat << EOF
【服务信息】
${service_config}
  ${line}
运行的服务:
${run_service}
  ${line}
监听端口:
${port_listen}
  ${line}
内核参考配置:
${kernel_config}
EOF
}

# 获取系统内存信息
get_mem_info() {
  check_mem=$(free -m)
  MemTotal=$(grep MemTotal /proc/meminfo | awk '{print $2}') #KB
  MemFree=$(grep MemFree /proc/meminfo | awk '{print $2}') #KB
  let MemUsed=MemTotal-MemFree
  MemPercent=$(awk "BEGIN {if($MemTotal==0){printf 100}else{printf \"%.2f\",$MemUsed*100/$MemTotal}}")
  report_MemTotal="$((MemTotal/1024))" "MB" #内存总容量(MB)
  report_MemFree="$((MemFree/1024))" "MB" #内存剩余(MB)
  report_MemUsedPercent=$(free | sed -n '2p' | gawk 'x = int(( $3 / $2 ) * 100) {print x}' | sed 's/$/%/')

  cat << EOF
【内存信息】
内存总容量(MB): ${report_MemTotal}
内存剩余量(MB):${report_MemFree}
内存使用率: ${report_MemUsedPercent}
EOF
}

# 获取系统网络信息
get_net_info() {
  pri_ipadd=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}')
  pub_ipadd=$(curl ifconfig.me -s)
  gateway=$(ip route | grep default | awk '{print $3}')
  mac_info=$(ip link | egrep -v "lo" | grep link | awk '{print $2}')
  dns_config=$(egrep -v "^$|^#" /etc/resolv.conf)
  route_info=$(route -n)
  cat << EOF
【网络信息】
系统公网地址:${pub_ipadd}
系统私网地址:${pri_ipadd}
网关地址:${gateway}
MAC地址:${mac_info}
路由信息:
${route_info}
DNS 信息:
${dns_config}
EOF
}

# 获取系统磁盘信息
get_disk_info() {
  disk_info=$(fdisk -l | grep "Disk /dev" | cut -d, -f1)
  disk_use=$(df -hTP | awk '$2!="tmpfs"{print}')
  disk_percent=$(free | sed -n '2p' | gawk 'x = int(( $3 / $2 ) * 100) {print x}' | sed 's/$/%/')
  disk_inode=$(df -hiP | awk '$1!="tmpfs"{print}')

  cat << EOF
【磁盘信息】
${disk_info}
磁盘使用: ${disk_use}
磁盘使用百分比: ${disk_percent}
inode信息: ${disk_inode}
EOF
}

# 获取系统用户信息
get_sys_user() {
  login_user=$(awk -F: '{if ($NF=="/bin/bash") print $0}' /etc/passwd)
  ssh_config=$(egrep -v "^#|^$" /etc/ssh/sshd_config)
  sudo_config=$(egrep -v "^#|^$" /etc/sudoers | grep -v "^Defaults")
  host_config=$(egrep -v "^#|^$" /etc/hosts)
  crond_config=$(for cronuser in /var/spool/cron/*; do
    ls ${cronuser} 2> /dev/null | cut -d/ -f5; egrep -v "^$|^#" ${cronuser} 2> /dev/null;
    echo "";
  done)
  cat << EOF
【用户信息】
系统登录用户:
${login_user}
  ${line}
ssh 配置信息:
${ssh_config}
  ${line}
sudo 配置用户:
${sudo_config}
  ${line}
定时任务配置:
${crond_config}
  ${line}
hosts 信息:
${host_config}
EOF
}

# 获取CPU/内存占用TOP10
get_process_top_info() {

  top_title=$(top -b n1 | head -7 | tail -1)
  cpu_top10=$(top -b n1 | head -17 | tail -11)
  mem_top10=$(top -b n1 | head -17 | tail -10 | sort -k10 -r)

  cat << EOF
【TOP10】
CPU占用TOP10:
${cpu_top10}
内存占用TOP10:
${top_title}
  ${mem_top10}
EOF
}

show_dead_process() {
  printf "僵尸进程:\n"
  ps -al | gawk '{print $2,$4}' | grep Z
}

get_all_info() {
  get_systatus_info
  echo ${double_line}
  get_service_info
  echo ${double_line}
  get_cpu_info
  echo ${double_line}
  get_net_info
  echo ${double_line}
  get_mem_info
  echo ${double_line}
  get_disk_info
  echo ${double_line}
  get_process_top_info
  echo ${double_line}
  get_sys_user
}

main() {
  while [[ 1 ]]
  do
    printMenu
    read option
    local index=$[ ${option} - 1 ]
    case ${options[${index}]} in
      "获取系统信息")
        get_systatus_info ;;
      "获取服务信息")
        get_service_info ;;
      "获取CPU信息")
        get_cpu_info ;;
      "获取系统网络信息")
        get_net_info ;;
      "获取系统内存信息")
        get_mem_info ;;
      "获取系统磁盘信息")
        get_disk_info ;;
      "获取CPU/内存占用TOP10")
        get_process_top_info ;;
      "获取系统用户信息")
        get_sys_user ;;
      "输出所有信息")
        get_all_info > sys.log
        printf "${C_GREEN}信息已经输出到 sys.log 中。${C_RESET}\n\n"
      ;;
      "退出")
        exit ;;
      *)
        clear
        echo "抱歉,不支持此选项" ;;
    esac
  done
}

######################################## MAIN ########################################
printHeadInfo
main
printFootInfo
printf "${C_RESET}"

SPN 日常巡查脚本

SPN(Secret Private Network),面向业务的内网安全解决方案,即加密虚拟网络

#!/bin/bash
echo "      ___           ___         ___
     /  /\         /  /\       /__/\
    /  /:/_       /  /::\      \  \:\
   /  /:/ /\     /  /:/\:\      \  \:\
  /  /:/ /::\   /  /:/~/:/  _____\__\:\
 /__/:/ /:/\:\ /__/:/ /:/  /__/::::::::\
 \  \:\/:/~/:/ \  \:\/:/   \  \:\~~\~~\/
  \  \::/ /:/   \  \::/     \  \:\  
   \__\/ /:/     \  \:\      \  \:\
     /__/:/       \  \:\      \  \:\
     \__\/         \__\/       \__\/
"
echo "SPN 日常巡查脚本输出"
# 清理屏幕
clear

function bash_os() {
    # "系统基础信息"

    #内核信息
    kernel=$(uname -r)
    #操作系统版本
    release=$(cat /etc/redhat-release)
    #主机名称
    hostname=$HOSTNAME
    #当前时间及运行时间
    dateload=$(uptime | awk -F "," '{print $1}')
    # 当前登录用户数
    users=$(uptime | awk -F "," '{print $3}')

    echo -e "\n\033[32m##############   系统基础信息 #######\033[0m\n"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|内核信息:\033[31m        $kernel           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|操作系统版本:\033[31m   $release        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|当前时间及运行时间:\033[31m   $dateload        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|当前登录用户数:\033[31m   $users        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
}

function memory() {

    # 内存相关数据统计`free -m`
    #总内存容量
    mem_total=$(free -m | awk '/Mem/{printf "%.2fG", $2/1024}')
    # 用户程序占用内存量
    mem_user=$(free -m | awk '/Mem/{printf "%.2fG", $3/1024}')
    #  多进程共享占用内存量
    mem_shared=$(free -m | awk '/Mem/{printf "%.2fG", $5/1024}')
    #缓存占用内存量
    mem_buff_cache=$(free -m | awk '/Mem/{printf "%.fMB",  $(NF-1)}')
    #空闲内存容量
    mem_free=$(free -m | awk '/Mem/{printf "%.2fG", $4/1024 }')
    # 剩余可用内存容量
    mem_available=$(free -m | awk 'NR==2{printf "%.2fG",$NF/1024}')
    # 可用内存使用占比
    mem_percentage=$(free -m | awk '/Mem/{printf "%.2f", $NF/$2*100}')
    #总的交换分区容量
    swap_total=$(free -m | awk '/Swap/{printf "%.2fG", $2/1024}')
    #用户使用的交换分区容量
    swap_user=$(free -m | awk '/Swap/{printf "%.2fG",$3/1024}')
    #剩余交换分区容量
    swap_free=$(free -m | awk '/Swap/{printf "%.2fG",$4/1024}')
    #可用交换分区占比
    swap_percentage=$(free -m | awk '/Swap/{printf "%.2f",$4/$2*100}')
    #占用内存资源最多的10个进程列表
    top_proc_mem=$(ps --no-headers -eo rss,args | sort -k1 -n -r | head -10)

    echo -e "\n\033[32m################## 内存 ############\033[0m\n"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|总内存容量:\033[31m        $mem_total           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|用户程序内存量:\033[31m   $mem_user        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|多进程共享内存量:\033[31m $mem_shared     \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|缓存占用内存量:\033[31m   $mem_buff_cache    \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|空闲内存容量:\033[31m     $mem_free           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|剩余可用内存容量:\033[31m  $mem_available    \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|可用内存百分比:\033[31m   $mem_percentage%   \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "\033[32m############## 交换分区 #############\033[0m\n"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "总的交换分区容量:\033[31m    $swap_total    \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|用户使用的交换分区容量:\033[31m   $swap_user   \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|剩余交换分区容量:\033[31m  ${swap_free}"
    echo -e "\033[32m------------------------------------\033[0m"
    if [ $(free -m | awk '/Swap/{print $2}') -ne 0 ]; then

        echo -e "|可用交换分区占比:\033[31m  $swap_percentage%    \033[0m"
        echo -e "\033[32m------------------------------------\033[0m"
    fi
    echo -e "|占用内存资源最多的10个进程列表:"
    echo -e "\033[31m$top_proc_mem%    \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
}

function cpu() {
    #CPU型号
    cpu_info=$(LANG=C lscpu | awk -F: '/Model name/ {print $2}')

    #CPU内核数量
    cpu_core=$(awk '/processor/{core++} END{print core}' /proc/cpuinfo)

    #CPU最近1/5/15分钟的平均负载
    load1515=$(uptime | sed 's/,/ /g' | awk '{for(i=NF-2;i<=NF;i++)print $i }' | xargs)

    #发生中断数量
    irq=$(vmstat 1 1 | awk 'NR==3{print $11}')

    #上下文切换数量
    cs=$(vmstat 1 1 | awk 'NR==3{print $12}')

    #占用CPU资源最多的10个进程列表
    top_proc_cpu=$(ps --no-headers -eo %cpu,args | sort -k1 -n -r | head -10)

    echo -e "\n\033[32m################## CPU 相关 ############\033[0m\n"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|CPU型号:\033[31m$cpu_info           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|CPU内核数量:\033[31m$cpu_core        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|CPU最近1/5/15分钟的平均负载:\033[31m$load1515        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|CPU中断数量:\033[31m$irq        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|上下文切换数量:\033[31m$cs        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|占用CPU资源最多的10个进程列表:"
    echo -e "\033[31m$top_proc_cpu           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"

}

function disk_io() {
    #分区挂载信息
    disk=$(df -h)
    # 磁盘总数
    disk_total=$(vmstat -D | awk 'NR==1{print $1}')
    # 分区总数
    disk_sub=$(vmstat -D | awk 'NR==2{print $1}')
    #磁盘分区信息
    lsblk_=$(lsblk -n)
    #写入磁盘的总块数
    bo=$(vmstat 1 1 | awk 'NR==3{print $10}')
    #从磁盘读出的块数
    bi=$(vmstat 1 1 | awk 'NR==3{print $9}')
    #每秒写磁盘块的速率
    wa=$(vmstat 1 1 | awk 'NR==3{print $16}')

    echo -e "\n\033[32m################## 磁盘IO 相关 ############\033[0m\n"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|磁盘总数:\033[31m$disk_total           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|分区总数:\033[31m$disk_sub        \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|磁盘分区信息:"
    echo -e "\033[31m$lsblk_           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|写入磁盘的总块数:\033[31m$bo       \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|从磁盘读出的块数:\033[31m$bi       \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|每秒写磁盘块的速率:\033[31m$wa       \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|分区挂载信息:"
    echo -e "\033[31m$disk           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"

}

function procs() {
    #进程数量
    procs=$(ps aux | wc -l)
    #用户的最大进程数
    ulimit_=$(ulimit -u)
    #内核设置的最大进程数
    pid_max=$(sysctl kernel.pid_max | awk '{print $3}')

    echo -e "\n\033[32m################## 进程 相关 ############\033[0m\n"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|进程数量:\033[31m$procs       \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|用户的最大进程数:\033[31m$ulimit_       \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|内核设置的最大进程数:\033[31m$pid_max       \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"

}

function network() {
    #获取网卡流量信息,接收|发送的数据流量,单位为字节(bytes)
    net_monitor=$(cat /proc/net/dev | tail -n +3 | awk 'BEGIN{ print "网卡名称 入站数据流量(bytes) 出站数据流量(bytes)"} {print $1,$2,$10}' | column -t)
    #获取暴露端口信息
    ip_port=$(ss -ntulpa)

     #本地IP地址列表
    localip=$(ip a s | awk '/inet /{print $2}' )


    echo -e "\n\033[32m################## 网络 相关 ############\033[0m\n"
    echo -e "|本地IP地址列表:"
    echo -e "\033[31m$localip    \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|获取网卡流量信息:"
    echo -e "\033[31m$net_monitor           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"
    echo -e "|获取暴露端口信息:"
    echo -e "\033[31m$ip_port           \033[0m"
    echo -e "\033[32m------------------------------------\033[0m"

}

case $1 in
all)
    bash_os
    memory
    cpu
    disk_io
    procs
    network
    ;;
bash_os)
    bash_os
    ;;
memory)
    memory
    ;;
cpu)
    cpu
    ;;
disk_io)
    disk_io
    ;;
procs)
    procs
    ;;
network)
    network
    ;;
*)
    echo "Usage: bash_os|memory|cup|disk_io|procs|network|all"
    ;;
esac

ffmpeg脚本

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序

打开进程,并判断进程数量

原版本:

#!/bin/bash
ffmpegPid = $( ps -ef | grep -E 'ffmpeg.*$1$2$3' | grep -v 'grep' | awk '{print $2}')
if [ -z "$ffmpegPid" ]
then
	threadNum = $( ps -ef | grep ffmpeg | grep -v 'grep' | wc -l | awk '{print $1}')
	if [$threadNum -gt 10]
	then
		# 线程数大于10个,需要干掉ffmpeg线程
		echo threadNum too more!
		for thread in $threadNum
		do
			kill -9 ${thread}
		done
	else
		nohup ffmpeg -re  -rtsp_transport tcp -i "rtsp://ip:port/dss/monitor/params?cameraid=$1%24$2&substream=$3" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 $4 > /Users/chuxiaowei/ffmpeg$1$2$3.log 2>&1 &
		ps -ef | grep -E 'ffmpeg.*$1$2$3' | grep -v 'grep' | awk '{print $2}'
	fi
else
	ps -ef | grep -E 'ffmpeg.*$1$2$3' | grep -v 'grep' | awk '{print $2}'
fi

改进之后:

#!/bin/bash
ffmpegPid = $( ps -ef | grep -E 'ffmpeg.*$1$2$3' | grep -v 'grep' | awk '{print $2}')
if [ -z "$ffmpegPid" ]
then
    nohup ffmpeg -re  -rtsp_transport tcp -i "rtsp://ip:port/dss/monitor/params?cameraid=$1%24$2&substream=$3" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 $4 > /root/ffmpeg$1$2$3.log 2>&1 &
    ps -ef | grep -E 'ffmpeg.*$4*' | grep -v 'grep' | awk '{print $2}'
fi

关闭进程

#关闭进程
#!/bin/bash
ps -ef | grep -E 'ffmpeg.*$1*' | grep -v 'grep' | awk '{print $2}' | xargs kill

java jar包启动-剔除Pom中依赖

#!/bin/bash
pid=$(ps -ef | grep java | grep -E '*rtsptortmp.*' | awk '{print $2}')
echo "pid = $pid"
if [ $pid ];then
    kill -9 $pid
    echo "kill the process rtsptortmp pid = $pid"
fi

nohup java -Dloader.path=/root/rtsptortmplib -jar rtsptortmp-1.0-SNAPSHOT.jar --spring.profiles.active=prod > /root/logs/rtsptortmp.log 2>&1 &
tail -f /root/logs/rtsptortmp.log

Java jar包通用启动脚本

eg:
./start.sh java.jar

#!/bin/bash
pid=$(ps -ef | grep java | grep -E '*$1*' | awk '{print $2}')
echo "pid = $pid"
if [ $pid ];then
    kill -9 $pid
    echo "kill the process pid = $pid"
fi

nohup java -jar -Xms256m -Xmx256m $1 --spring.profiles.active=prod > /root/logs/$1.log 2>&1 &
tail -f /root/logs/$1.log

查看centos配置信息脚本

#!/bin/bash

echo ======= cpu个数: =======
grep 'physical id' /proc/cpuinfo | sort -u | wc -l

echo ======= cpu核数: =======
cat /proc/cpuinfo | grep "cpu cores" | uniq

echo ======= cpu型号: =======
cat /proc/cpuinfo | grep 'model name' |uniq

echo ======= cpu内核频率: =======
cat /proc/cpuinfo |grep MHz|uniq

echo ======= cpu统计信息: =======
lscpu

echo ======= 内存总数: =======
cat /proc/meminfo | grep MemTotal

echo ======= 内核版本: =======
cat /proc/version

echo ======= 操作系统内核信息: =======
uname -a

echo ======= 磁盘信息: =======
fdisk -l

Jenkins项目打包发布脚本

#!/bin/bash

//传入的war包名称
name=$1 	
//war包所在目录							
path=$2
//上传的war包位置				
path_w=$3		
//如果项目正在运行就杀死进程
if [ -f "$path/$name" ];then
	echo "delete the file $name"
	rm -f  $path/$name
else
	echo "the file $name is not exist"
fi
//把jenkins上传的war包拷贝到我们所在目录 
cp $path_w/$name $path/
echo "copy the file $name from $path_w to $path"

//获取该项目正在运行的pid			
pid=$(ps -ef | grep java | grep $name | awk '{print $2}')
echo "pid = $pid"
//如果项目正在运行就杀死进程
if [ $pid ];then
	kill -9 $pid
	echo "kill the process $name pid = $pid"
else
	echo "process is not exist"
fi
//要切换到项目目录下才能在项目目录下生成日志
cd $path
//防止被jenkins杀掉进程 BUILD_ID=dontKillMe
BUILD_ID=dontKillMe
//启动项目
nohup java -server -Xms256m -Xmx512m -jar -Dserver.port=20000 $name >> nohup.out 2>&1 &
//判断项目是否启动成功
pid_new=$(ps -ef | grep java | grep $name | awk '{print $2}')
if [ $? -eq 0 ];then
echo "this application  $name is starting  pid_new = $pid_new"
else 
echo "this application  $name  startup failure"
fi
echo $! > /var/run/myClass.pid
echo "over"

Mysql-使用脚本进行分库分表备份

[root@ctos3 ~]# cat bak.sh
#!/bin/bash

MYUSER="root"
MYPASS="guoke123"
MYLOG="mysql -u$MYUSER -p$MYPASS -e"
MYDUMP="mysqldump -u$MYUSER -p$MYPASS -x -F"
DBLIST=$($MYLOG  "show databases;" | sed 1d | grep -Ev 'info|mysq|per|sys')
DIR=/backup
[ ! -d $DIR ] && mkdir $DIR
cd $DIR

for dbname in $DBLIST
do
 TABLIST=$($MYLOG "show tables from $dbname;" | sed 1d)
for tabname in $TABLIST
do
  mkdir -p $DIR/$dbname
   $MYDUMP $dbname $tabname  --events |gzip > $DIR/${dbname}/${tabname}_$(date +%F_%T).sql.gz
done
done

监控某个目录是否被更改

需求:对一个目录(比如/data/test)进行监控,当这个目录下文件或子目录出现变动(如修改、创建、删除、更名等操作)时,就发送邮件!
针对上面的需求,编写shell脚本如下:

[root@centos6-vm01 opt]# vim file_monit.sh
#!/bin/bash
#此脚本用于检测linux系统重要文件是否被改动,如果改动则用邮件报警
#建议用定时任务执行此脚本,如每5分钟执行一次,也可修改此脚本用于死循环检测
#Ver:1.0
#http://www.cnblogs.com/kevingrace
 
#定义验证文件所在目录
FileDir='/var/CheckFile'
 
#获取主机名或自己定义
HostName=$(hostname)
 
#定义邮件参数:xmtp地址,发送邮件帐号,发送邮件密码,接收邮件地址,邮件主题,邮件内容
Mail_Smtp="smtp.wangshibo.com"
Mail_User="notice@wangshibo.com"
Mail_Pass="notice@123"
Mail_From="notice@wangshibo.com"
Mail_To="wangshibo@wangshibo.com"
Mail_Subject="${HostName}:There are changes to system files"
Mail_Conntent="${HostName}:There are changes to system files"
 
#定义需要验证的文件目录。这里我监控的是/data/test目录
CheckDir=(
/data/test
)
 
#生成所定义需验证的文件样本日志函数
OldFile () {
for i in ${CheckDir[@]}
do
/bin/find ${i} -type f |xargs md5sum >> ${FileDir}/old.log
done
}
NewFile () {
for i in ${CheckDir[@]}
do
/bin/find ${i} -type f |xargs md5sum >> ${FileDir}/new.log
done
}
 
#生成所定义文件新日志函数(注意后面发送邮件内容,\n表示换行)
SendEMail () {
/usr/local/bin/sendEmail -f $Mail_From -t $Mail_To -s $Mail_Smtp -u $Mail_Subject -xu $Mail_User -xp $Mail_Pass -m "$Mail_Conntent"\n
}
if [ ! -d ${FileDir} ]
then
mkdir ${FileDir}
fi
 
#假如验证文件目录不存在则创建
if [ ! -f ${FileDir}/old.log ]
then
OldFile
fi
 
#假如没有安装sendEmail则安装
if [ ! -f /usr/local/bin/sendEmail ]
then
cd /usr/local/src/
wget http://caspian.dotconf.net/menu/Software/SendEmail/sendEmail-v1.56.tar.gz
tar -xf sendEmail-v1.56.tar.gz
cd sendEmail-v1.56
cp sendEmail /usr/local/bin
chmod 0755 /usr/local/bin/sendEmail
fi
 
#生成新验证日志
NewFile
 
#新验证日志与样本日志进行比较
/usr/bin/diff ${FileDir}/new.log ${FileDir}/old.log >${FileDir}/diff.log
Status=$?
 
#假如比较结果有变化,则发送邮件报警
if [ ${Status} -ne 0 ]
then
Mail_Conntent="$(grep '<' ${FileDir}/diff.log |awk '{print $3}')"
SendEMail
fi
 
#清除新旧日志,把比较结果进行备份
/bin/mv -f ${FileDir}/diff.log ${FileDir}/diff$(date +%F__%T).log
cat /dev/null > ${FileDir}/old.log
cat /dev/null > ${FileDir}/new.log
 
#重新生成样本日志
OldFile
 
#删除目录内30天以前的比较结果备份文件
/bin/find ${FileDir} -type f -mtime +30 |xargs rm -f

确保本机能连上shell脚本中指定的smtp服务器的25好端口

[root@centos6-vm01 opt]# telnet smtp.wangshibo.com 25
Trying 223.252.214.65...
Connected to smtp.wangshibo.com.
Escape character is '^]'.
220 icoremail.net Anti-spam GT for Coremail System (icoremail-gateway-smtp[20170531])

下面开始测试

[root@centos6-vm01 test]# cd /opt/
[root@centos6-vm01 opt]# cd /data/test/
[root@centos6-vm01 test]# ll
total 0
[root@centos6-vm01 test]# mkdir haha
[root@centos6-vm01 test]# echo "123456" > haha/heihei
[root@centos6-vm01 test]# ll
total 4
drwxr-xr-x. 2 root root 4096 Jan 10 01:42 haha
[root@centos6-vm01 test]# echo "abcdef" > test.txt
[root@centos6-vm01 test]# ll
total 8
drwxr-xr-x. 2 root root 4096 Jan 10 01:42 haha
-rw-r--r--. 1 root root    7 Jan 10 01:42 test.txt
 
执行监控脚本
[root@centos6-vm01 test]# sh -x /opt/file_monit.sh
 
注意:当首次执行脚本的时候,由于所监控的目录下的文件没有变动,所以不会发送邮件!
 
查看对比后的日志
[root@centos6-vm01 test]# ll -d /var/CheckFile/
drwxr-xr-x. 2 root root 4096 Jan 10 01:44 /var/CheckFile/
[root@centos6-vm01 test]# ll /var/CheckFile/
total 4
-rw-r--r--. 1 root root   0 Jan 10 01:44 diff2018-01-10__01:44:30.log
-rw-r--r--. 1 root root   0 Jan 10 01:44 new.log
-rw-r--r--. 1 root root 166 Jan 10 01:44 old.log
 
[root@centos6-vm01 test]# cat /var/CheckFile/diff2018-01-10__01\:44\:30.log
[root@centos6-vm01 test]# cat /var/CheckFile/new.log                       
[root@centos6-vm01 test]# cat /var/CheckFile/old.log
237267ea7fefa88360c22ab6fd582d7e  /data/test/.hhhh.swp
5ab557c937e38f15291c04b7e99544ad  /data/test/test.txt
f447b20a7fcbf53a5d5be013ea0b15af  /data/test/haha/heihei
 
 
==============================================================================================================================
现在开始对/data/test目录下的文件做下变动
[root@centos6-vm01 test]# echo "aaaaaa" >> test.txt
[root@centos6-vm01 test]# touch haha/bobo
[root@centos6-vm01 test]# mkdir heihei
[root@centos6-vm01 test]# ll
total 12
drwxr-xr-x. 2 root root 4096 Jan 10 01:47 haha
drwxr-xr-x. 2 root root 4096 Jan 10 01:47 heihei
-rw-r--r--. 1 root root   14 Jan 10 01:47 test.txt
 
执行监控脚本
[root@centos6-vm01 test]# sh -x /opt/file_monit.sh
 
 
查看对比后的日志
[root@centos6-vm01 test]# ll /var/CheckFile/
total 8
-rw-r--r--. 1 root root   0 Jan 10 01:44 diff2018-01-10__01:44:30.log
-rw-r--r--. 1 root root 179 Jan 10 01:47 diff2018-01-10__01:47:41.log
-rw-r--r--. 1 root root   0 Jan 10 01:47 new.log
-rw-r--r--. 1 root root 221 Jan 10 01:47 old.log
[root@centos6-vm01 test]# cat /var/CheckFile/diff2018-01-10__01\:47\:41.log
2,3c2
< 4533551682ca49b2f9b1f2829bf3b29d  /data/test/test.txt
< d41d8cd98f00b204e9800998ecf8427e  /data/test/haha/bobo
---
> 5ab557c937e38f15291c04b7e99544ad  /data/test/test.txt
 
[root@centos6-vm01 test]# cat /var/CheckFile/old.log
237267ea7fefa88360c22ab6fd582d7e  /data/test/.hhhh.swp
4533551682ca49b2f9b1f2829bf3b29d  /data/test/test.txt
d41d8cd98f00b204e9800998ecf8427e  /data/test/haha/bobo
f447b20a7fcbf53a5d5be013ea0b15af  /data/test/haha/heihei
 
通过上面的diff日志,可以看到新变动的文件或子目录已经记录到日志里了。

查看邮件,就能看到/data/test目录下变动的文件或子目录信息了

在这里插入图片描述

通过crontab定时任务,每5分钟执行一次检查:

[root@centos6-vm01 test]# crontab -e
*/5 * * * *  /bin/bash -x /opt/file_monit.sh > /dev/null 2>&1

以上脚本也可以用于检测linux系统重要文件是否被更改,只需将检查的目录由脚本中的/data/test改为/etc即可!

日志文件ERROR监控报警

即对日志文件中的error进行监控,当日志文件中出现error关键字时,即可报警!(grep -i error 不区分大小写进行搜索"error"关键字,但是会将包含error大小写字符的单词搜索出来)

1)第一类日志

在每天的日志目录下生产的error日志,此日志文件每天都会自动生成,里面有没有error日志内容不一定,日志内容写入不频繁,日志文件比较小。
举例说明:

[root@fk-databus01 ~]# ll /data/log/sedsb/20180628/DEJ_0001_error_20180628.0.log
-rw-rw-r-- 1 zquser zquser 63059 Jun 28 15:32 /data/log/sedsb/20180628/DEJ_0001_error_20180628.0.log
        
采用sendemail发送告警邮件,sendemail安装参考:http://www.cnblogs.com/kevingrace/p/5961861.html
        
监控脚本路径:
[root@fk-databus01 ~]# cd /opt/log_error_script/
[root@fk-databus01 log_error_script]# ll
total 20
-rw-r--r-- 1 root root 3782 Jun 29 12:13 DEJ_0001_error.log
-rwxr-xr-x 1 root root 4274 Jun 29 11:38 prcc_log_error.sh
-rwxr-xr-x 1 root root 1142 Feb 13 10:51 sendemail.sh
      
监控脚本内容
[root@fk-databus01 log_error_script]# cat prcc_log_error.sh
#!/bin/sh
ERROR_LOG=`/bin/ls /data/log/sedsb/$(date +%Y%m%d)/DEJ_0001_error*`
ERROR_NEW_LOG=/opt/log_error_script/DEJ_0001_error.log
DATE=`date +%Y%m月%d日%H%M%S秒`
HOST=`/bin/hostname`
IP=`/sbin/ifconfig|grep "inet addr"|grep "Bcast"|cut -d":" -f2|awk -F" " '{print $1}'`
ERROR_MESSAGE=$(/bin/grep -A20 "$(grep "ERROR" $ERROR_LOG|tail -1|awk '{print $1,$2,$3,$4}')" $ERROR_LOG)
    
DIR=/data/log/sedsb/$(date +%Y%m%d)
FILE=/data/log/sedsb/$(date +%Y%m%d)/DEJ_0001_error_$(date +%Y%m%d).0.log
     
if [ ! -d $DIR ];then
   /bin/mkdir $DIR
fi
     
if [ ! -f $FILE ];then
   /bin/touch $FILE
fi
     
/bin/chown -R zquser.zquser $DIR
 
sleep 3
     
if [ ! -f $ERROR_NEW_LOG ];then
/bin/touch $ERROR_NEW_LOG
fi
        
NUM1=$(/bin/cat $ERROR_LOG|wc -l)
NUM2=$(/bin/cat $ERROR_NEW_LOG|wc -l)
        
if [ -f $ERROR_LOG ] && [ $NUM1 -ne 0 ] && [ $NUM2 -eq 0 ];then
/bin/bash /opt/log_error_script/sendemail.sh wangshibo@kevin.com "风控系统${HOSTNAME}机器prcc服务日志的error监控" "告警主机:${HOSTNAME} \n告警IP:${IP} \n告警时间:${DATE} \n告警等级:严重,抓紧解决啊! \n告警人员:王士博 \n告警详情:prcc服务日志中出现error了! \n告警日志文件:${ERROR_LOG} \n当前状态: PROBLEM  \n  \nerror信息:\n$ERROR_MESSAGE"
/bin/cat $ERROR_LOG > $ERROR_NEW_LOG
fi
        
/usr/bin/cmp $ERROR_LOG $ERROR_NEW_LOG >/dev/null 2>&1
if [ $? -ne 0 ];then
/bin/bash /opt/log_error_script/sendemail.sh wangshibo@kevin.com "风控系统${HOSTNAME}机器prcc服务日志的error监控" "告警主机:${HOSTNAME} \n告警IP:${IP} \n告警时间:${DATE} \n告警等级:严重,抓紧解决啊! \n告警人员:王士博 \n告警详情:prcc服务日志中出现error了! \n告警日志文件:${ERROR_LOG} \n当前状态: PROBLEM  \n  \nerror信息:\n$ERROR_MESSAGE"
/bin/cat $ERROR_LOG > $ERROR_NEW_LOG
fi
        
结合crontab进行定时监控(15秒执行一次)
[root@fk-databus01 ~]# crontab -l
#监控pcrr日志的error
* * * * * /bin/bash -x /opt/log_error_script/prcc_log_error.sh >/dev/null 2>&1
* * * * * sleep 15;/bin/bash -x /opt/log_error_script/prcc_log_error.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/prcc_log_error.sh >/dev/null 2>&1
* * * * * sleep 45;/bin/bash -x /opt/log_error_script/prcc_log_error.sh >/dev/null 2>&1
   
==================================================================================
针对上面脚本中的某些变量说明
[root@fk-databus01 ~]# /bin/ls /data/log/sedsb/$(date +%Y%m%d)/DEJ_0001_error*
/data/log/sedsb/20180629/DEJ_0001_error_20180629.0.log
   
[root@fk-databus01 ~]# grep "ERROR" /data/log/sedsb/20180629/DEJ_0001_error_20180629.0.log
ERROR DEJ 2018-06-29 12:13:29.191 [pool-4-thread-10] n.s.p.r.thread.OuterCheThdInterface - cx201806291213288440016车300接口异常!
ERROR DEJ 2018-06-29 12:13:29.196 [nioEventLoopGroup-3-12] n.s.p.r.c.MessageControllerImpl - cx201806291213288440016:
   
[root@fk-databus01 ~]# grep "ERROR" /data/log/sedsb/20180629/DEJ_0001_error_20180629.0.log |tail -1|awk '{print $1,$2,$3,$4}'
ERROR DEJ 2018-06-29 12:13:29.196
   
[root@fk-databus01 ~]# /bin/grep -A20 "$(grep "ERROR" /data/log/sedsb/20180629/DEJ_0001_error_20180629.0.log |tail -1|awk '{print $1,$2,$3,$4}')" /data/log/sedsb/20180629/DEJ_0001_error_20180629.0.log
ERROR DEJ 2018-06-29 12:13:29.196 [nioEventLoopGroup-3-12] n.s.p.r.c.MessageControllerImpl - cx201806291213288440016:
net.sinocredit.pre.rcc.utils.exception.OuterDataException: 外部数据:cheFixPrice:mile里程  is null;
   at net.sinocredit.pre.rcc.datafactory.OuterDataProcess.execute(OuterDataProcess.java:51)
   at net.sinocredit.pre.rcc.datafactory.OuterDataProcess.execute(OuterDataProcess.java:23)
   at net.sinocredit.pre.rcc.service.getOtherDataService.MessageServiceImpl.getOrderData(MessageServiceImpl.java:34)
   at net.sinocredit.pre.rcc.controller.MessageControllerImpl.divMessage(MessageControllerImpl.java:110)
   at net.sinocredit.pre.rcc.handler.ServerHandler.channelRead(ServerHandler.java:28)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:373)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
   at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:351)
   at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:373)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
   at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:351)
   at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:293)
   at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:267)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:373)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:359)
   at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:351)
   at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1334)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:373)

报警邮件效果如下:
在这里插入图片描述

2)第二类日志

此日志是固定文件,日志内容写入频繁,日志文件比较大。对于此文件的监控,通过采用tail -1000方式获取日志文件的最新1000行的方式进行error监控!
举例说明:

[root@fk-zqjcweb01 ~]# ll /data/log/decision/decision.log
-rw-rw-r-- 1 zquser zquser 5108 Jun 28 16:02 /data/log/decision/decision.log
 
采用sendemail发送告警邮件,sendemail安装参考:http://10.0.8.50/software/sendemail_install.sh
 
监控脚本路径:
[root@fk-zqjcweb01 ~]# cd /opt/log_error_script/
[root@fk-zqjcweb01 log_error_script]# ls
decision sendemail.sh
[root@fk-zqjcweb01 log_error_script]# ls decision/
decision.log_diff_error.log decision.log_error.log decision.log_monit.sh
 
脚本内容:
[root@fk-zqjcweb01 log_error_script]# cat decision/decision.log_monit.sh
#!/bin/sh
ERROR_LOG=/data/log/decision/decision.log
ERROR_NEW_LOG=/opt/log_error_script/decision/decision.log_error.log
ERROR_DIFF_LOG=/opt/log_error_script/decision/decision.log_diff_error.log
DATE=`date +%Y%m月%d日%H%M%S秒`
HOST=`/bin/hostname`
IP=`/sbin/ifconfig|grep "inet addr"|grep "Bcast"|cut -d":" -f2|awk -F" " '{print $1}'`
 
if [ ! -f $ERROR_NEW_LOG ];then
/bin/touch $ERROR_NEW_LOG
fi
 
NUM1=$(/usr/bin/tail -1000 $ERROR_LOG|grep error|wc -l)
NUM2=$(/bin/cat $ERROR_NEW_LOG|wc -l)
 
if [ -f $ERROR_LOG ] && [ $NUM1 -ne 0 ] && [ $NUM2 -eq 0 ];then
/bin/bash /opt/log_error_script/sendemail.sh wangshibo@kevin.com "风控系统${HOSTNAME}机器的decision.log日志中的error监控" "告警主机:${HOSTNAME} \n告警IP:${IP} \n告警时间:${DATE} \n告警等级:严重,抓紧解决啊! \n告警人员:王士博 \n告警详情:decision.log日志中出现error了! \n告警日志文件:${ERROR_LOG} \n当前状态: PROBLEM "
/usr/bin/tail -1000 $ERROR_LOG|grep error > $ERROR_NEW_LOG
fi
 
/usr/bin/tail -1000 $ERROR_LOG|grep error > $ERROR_DIFF_LOG
/usr/bin/cmp $ERROR_DIFF_LOG $ERROR_NEW_LOG >/dev/null 2>&1
if [ $? -ne 0 ];then
/bin/bash /opt/log_error_script/sendemail.sh wangshibo@kevin.com "风控系统${HOSTNAME}机器的decision.log日志中的error监控" "告警主机:${HOSTNAME} \n告警IP:${IP} \n告警时间:${DATE} \n告警等级:严重,抓紧解决啊! \n告警人员:王士博 \n告警详情:decision.log日志中出现error了! \n告警日志文件:${ERROR_LOG} \n当前状态: PROBLEM "
/usr/bin/tail -1000 $ERROR_LOG|grep error > $ERROR_NEW_LOG
fi
You have new mail in /var/spool/mail/root
 
结合crontab进行定时监控
[root@fk-zqjcweb01 log_error_script]# crontab -l
#decision.log日志的error监控
* * * * * /bin/bash -x /opt/log_error_script/decision/decision.log_monit.sh >/dev/null 2>&1
* * * * * sleep 15;/bin/bash -x /opt/log_error_script/decision/decision.log_monit.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/decision/decision.log_monit.sh >/dev/null 2>&1
* * * * * sleep 45;/bin/bash -x /opt/log_error_script/decision/decision.log_monit.sh >/dev/null 2>&1

上面提到的sendemail.sh邮件发送脚本

[root@fk-zqjcweb01 ~]# cat /opt/log_error_script/sendemail.sh
#!/bin/bash
# Filename: SendEmail.sh
# Notes: 使用sendEmail
#
# 脚本的日志文件
LOGFILE="/tmp/Email.log"
:>"$LOGFILE"
exec 1>"$LOGFILE"
exec 2>&1
SMTP_server='smtp.kevin.com'
username='monit@kevin.com'
password='monit@123'
from_email_address='monit@kevin.com'
to_email_address="$1"
message_subject_utf8="$2"
message_body_utf8="$3"
# 转换邮件标题为GB2312,解决邮件标题含有中文,收到邮件显示乱码的问题。
message_subject_gb2312=`iconv -t GB2312 -f UTF-8 << EOF
$message_subject_utf8
EOF`
[ $? -eq 0 ] && message_subject="$message_subject_gb2312" || message_subject="$message_subject_utf8"
# 转换邮件内容为GB2312,解决收到邮件内容乱码
message_body_gb2312=`iconv -t GB2312 -f UTF-8 << EOF
$message_body_utf8
EOF`
[ $? -eq 0 ] && message_body="$message_body_gb2312" || message_body="$message_body_utf8"
# 发送邮件
sendEmail='/usr/local/bin/sendEmail'
set -x
$sendEmail -s "$SMTP_server" -xu "$username" -xp "$password" -f "$from_email_address" -t "$to_email_address" -u "$message_subject" -m "$message_body" -o message-content-type=text -o message-charset=gb2312

3)第三类日志

日志规则说明:

  • 在etl服务器下的EXP、MDB、MID、ODB、PDB、PUS、SDB系统里有很多任务日志,日志都存放在当天的日期目录下。
  • 现在需要对这些任务日志的error进行监控,当出现error报错信息时立刻发出报警!
  • 当这些任务日志文件里有出现error报错信息的,那么该任务日志文件就不会被写入了。也就是说一个任务日志文件只会出现一次error报错。
  • 出现error报错信息的任务日志不能删除和更改,因为这些任务日志会被其他程序调用展示。
[root@bigdata-etl01 ~]# ll /data/etluser/LOG/
drwxrwx--- 33 etluser etluser     4096 Jul  6 02:00 EXP
drwxrwx--- 33 etluser etluser     4096 Jul  6 02:00 MDB
drwxrwx--- 33 etluser etluser     4096 Jul  6 02:00 MID
drwxrwx--- 33 etluser etluser     4096 Jul  6 02:00 ODB
drwxrwx--- 33 etluser etluser     4096 Jul  6 02:00 PDB
drwxrwx--- 32 etluser etluser     4096 Jul  6 00:47 PUS
drwxrwx--- 33 etluser etluser     4096 Jul  6 02:00 SDB
[root@bigdata-etl01 ~]# ls /data/etluser/LOG/EXP/
20180606  20180609  20180612  20180615  20180618  20180621  20180624  20180627  20180630  20180703  20180706
20180607  20180610  20180613  20180616  20180619  20180622  20180625  20180628  20180701  20180704
20180608  20180611  20180614  20180617  20180620  20180623  20180626  20180629  20180702  20180705
[root@bigdata-etl01 ~]# ls /data/etluser/LOG/EXP/20180706/
EXP_EXP_V_CUST_CRDT_SITU_20180705[1][1].54.log                exp_v_opr_size_curr_stats_0010601[1].pl.56.log
EXP_EXP_V_DAILY_BIZ_AMT_SITU_20180705[1][1].45.log            exp_v_opr_size_curr_stats_0010602[1].pl.56.log
EXP_EXP_V_MATR_RMND_INTFC_QG6_001_20180705[1][1].83.log       exp_v_prvs_provs_int_intfc_f0_0010600[1].pl.103.log
EXP_EXP_V_OPR_SIZE_CURR_STATS_001_20180705[1][1].56.log       exp_v_prvs_provs_int_intfc_f0_0010601[1].pl.103.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F0_001_20180705[1][1].103.log  exp_v_prvs_provs_int_intfc_f0_0020600[1].pl.98.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F0_002_20180705[1][1].98.log   exp_v_prvs_provs_int_intfc_f0_0020601[1].pl.98.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F0_003_20180705[1][1].90.log   exp_v_prvs_provs_int_intfc_f0_0030600[1].pl.90.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F0_007_20180705[1][1].48.log   exp_v_prvs_provs_int_intfc_f0_0030601[1].pl.90.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F0_008_20180705[1][1].78.log   exp_v_prvs_provs_int_intfc_f0_0070600[1].pl.48.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F0_009_20180705[1][1].15.log   exp_v_prvs_provs_int_intfc_f0_0070601[1].pl.48.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F0_010_20180705[1][1].48.log   exp_v_prvs_provs_int_intfc_f0_0080600[1].pl.78.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F1_004_20180705[1][1].16.log   exp_v_prvs_provs_int_intfc_f0_0080601[1].pl.78.log
EXP_EXP_V_PRVS_PROVS_INT_INTFC_F1_006_20180705[1][1].8.log    exp_v_prvs_provs_int_intfc_f0_0090600[1].pl.15.log
EXP_EXP_V_QRY_FACT_AGT_INTFC_20180705[1][1].47.log            exp_v_prvs_provs_int_intfc_f0_0090601[1].pl.15.log
exp_v_cust_crdt_situ0600[1].pl.54.log                         exp_v_prvs_provs_int_intfc_f0_0100600[1].pl.48.log
exp_v_cust_crdt_situ0601[1].pl.54.log                         exp_v_prvs_provs_int_intfc_f0_0100601[1].pl.48.log
exp_v_cust_crdt_situ0602[1].pl.54.log                         exp_v_prvs_provs_int_intfc_f1_0040600[1].pl.16.log
exp_v_daily_biz_amt_situ0600[1].pl.45.log                     exp_v_prvs_provs_int_intfc_f1_0040601[1].pl.16.log
exp_v_daily_biz_amt_situ0601[1].pl.45.log                     exp_v_prvs_provs_int_intfc_f1_0060600[1].pl.8.log
exp_v_daily_biz_amt_situ0602[1].pl.45.log                     exp_v_prvs_provs_int_intfc_f1_0060601[1].pl.8.log
exp_v_matr_rmnd_intfc_qg6_0010600[1].pl.83.log                exp_v_qry_fact_agt_intfc0600[1].pl.47.log
exp_v_matr_rmnd_intfc_qg6_0010601[1].pl.83.log                exp_v_qry_fact_agt_intfc0601[1].pl.47.log
exp_v_matr_rmnd_intfc_qg6_0010602[1].pl.83.log                exp_v_qry_fact_agt_intfc0602[1].pl.47.log
exp_v_opr_size_curr_stats_0010600[1].pl.56.log
  
监控脚本思路:
1)对这些任务日志进行批量搜索error关键字(不区分大小写)
2)将出现error关键字的任务日志拷贝到一个专门的目录下(error日志文件的列表目录)。
3)对搜索到error关键字的任务日志做判断,判断它是否存在于那个列表目录下:
   如果不存在,说明是新出现error的日志文件,就立刻报警!
   如果存在,说明出现的error是之前的信息,不报警!
  
监控脚本编写情况如下:
error_log为error日志文件的列表目录;
sendemail.sh为邮件发送脚本(上面介绍过)
[root@bigdata-etl01 log_error_script]# ls
EXP  MDB  MID  ODB  PDB  PUS  SDB  sendemail.sh
[root@bigdata-etl01 log_error_script]# ls EXP/
error_log  EXP_error_monit.sh
[root@bigdata-etl01 log_error_script]# ls MDB/
error_log  MDB_error_monit.sh
[root@bigdata-etl01 log_error_script]# ls MID/
error_log  MID_error_monit.sh
[root@bigdata-etl01 log_error_script]# ls ODB/
error_log  ODB_error_monit.sh
[root@bigdata-etl01 log_error_script]# ls PDB/
error_log  PDB_error_monit.sh
[root@bigdata-etl01 log_error_script]# ls PUS/
error_log  PUS_error_monit.sh
[root@bigdata-etl01 log_error_script]# ls SDB/
error_log  SDB_error_monit.sh
[root@bigdata-etl01 log_error_script]#
  
这里贴出SDB系统的任务日志的error监控报警脚本(其他几个系统的监控脚本与这个一样,只需要将脚本中的SDB替换成对应的系统名称即可!)
[root@bigdata-etl01 log_error_script]# cat /opt/log_error_script/SDB/SDB_error_monit.sh
#!/bin/sh
DATE_DIR=$(date +%Y%m%d)
DATE=`date +%Y%m月%d日%H%M%S秒`
HOST=`/bin/hostname`
IP=`/sbin/ifconfig|grep "inet addr"|grep "Bcast"|cut -d":" -f2|awk -F" " '{print $1}'`
  
cd /data/etluser/LOG/SDB
if [ ! -d $DATE_DIR ];then
/bin/mkdir $DATE_DIR
/bin/chown -R etluser.etluser $DATE_DIR
fi
  
cd /data/etluser/LOG/SDB/$DATE_DIR
for FILE in $(/bin/ls *.log)
do
   NUM=$(/bin/grep -i "error" /data/etluser/LOG/SDB/$DATE_DIR/$FILE|wc -l)
   ERROR_MESSAGE=$(/bin/grep -i "error" /data/etluser/LOG/SDB/$DATE_DIR/$FILE)
   if [ $NUM -ne 0 ];then
      /bin/ls /opt/log_error_script/SDB/error_log/$FILE
      a=$?
      if [ $a -ne 0 ];then
          /opt/log_error_script/sendemail.sh wangshibo@test.com "大数据平台etl服务器${HOSTNAME}的SDB任务日志里出现error了" "告警主机:${HOSTNAME} \n告警IP:${IP} \n告警时间:${DATE} \n告警等级:严重 \n告警人员:王士博 \n告警详情:SDB的任务日志里出现error了,抓紧解决啊! \n当前状态: PROBLEM \n告警日志文件:/data/etluser/LOG/SDB/$DATE_DIR/$FILE \n\n\n------请看下面error报错信息------- \nerror信息:\n$ERROR_MESSAGE"
          cp /data/etluser/LOG/SDB/$DATE_DIR/$FILE /opt/log_error_script/SDB/error_log/
      else
          echo "$FILE日志中error报错信息是之前发生的,无需报警!"
      fi
   else
      echo "$FILE 日志里没有error报错啦"
   fi
done
  
给脚本赋予执行权限
[root@bigdata-etl01 log_error_script]# chmod 755 /opt/log_error_script/SDB/SDB_error_monit.sh
[root@bigdata-etl01 log_error_script]# sh /opt/log_error_script/SDB/SDB_error_monit.sh
qbl_biz_cst_bsc_inf0100[1].pl.73.log 日志里没有error报错啦
qbl_biz_cst_bsc_inf0101[1].pl.73.log 日志里没有error报错啦
qbl_biz_fnc_bsc_inf0100[1].pl.73.log 日志里没有error报错啦
qbl_biz_fnc_bsc_inf0101[1].pl.73.log 日志里没有error报错啦
qbl_biz_fnc_mod_inf0100[1].pl.73.log 日志里没有error报错啦
qbl_biz_fnc_mod_inf0101[1].pl.73.log 日志里没有error报错啦
qbl_biz_pd_bsc_inf0100[1].pl.73.log 日志里没有error报错啦
qbl_biz_pd_bsc_inf0101[1].pl.73.log 日志里没有error报错啦
qbl_biz_pre_ctr_bsc_inf0100[1].pl.73.log 日志里没有error报错啦
qbl_biz_pre_ctr_bsc_inf0101[1].pl.73.log 日志里没有error报错啦
qbl_biz_repy_base_inf0100[1].pl.73.log 日志里没有error报错啦
qbl_biz_repy_base_inf0101[1].pl.73.log 日志里没有error报错啦
qbl_biz_repy_pl_dtl0100[1].pl.78.log 日志里没有error报错啦
qbl_biz_repy_pl_dtl0101[1].pl.78.log 日志里没有error报错啦
qbl_biz_repy_pl_inf0100[1].pl.78.log 日志里没有error报错啦
qbl_biz_repy_pl_inf0101[1].pl.78.log 日志里没有error报错啦
qbl_biz_repy_rcrd_jrnl0100[1].pl.73.log 日志里没有error报错啦
qbl_biz_repy_rcrd_jrnl0101[1].pl.73.log 日志里没有error报错啦
.......
.......
  
结合crontab指定脚本定时执行任务(每30秒执行一次)
[root@bigdata-etl01 ~]# crontab -l
#etl相关任务日志的error监控报警
* * * * * /bin/bash -x /opt/log_error_script/EXP/EXP_error_monit.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/EXP/EXP_error_monit.sh >/dev/null 2>&1
  
* * * * * /bin/bash -x /opt/log_error_script/MDB/MDB_error_monit.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/MDB/MDB_error_monit.sh >/dev/null 2>&1
  
* * * * * /bin/bash -x /opt/log_error_script/MID/MID_error_monit.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/MID/MID_error_monit.sh >/dev/null 2>&1
  
* * * * * /bin/bash -x /opt/log_error_script/ODB/ODB_error_monit.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/ODB/ODB_error_monit.sh >/dev/null 2>&1
  
* * * * * /bin/bash -x /opt/log_error_script/PDB/PDB_error_monit.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/PDB/PDB_error_monit.sh >/dev/null 2>&1
  
* * * * * /bin/bash -x /opt/log_error_script/PUS/PUS_error_monit.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/PUS/PUS_error_monit.sh >/dev/null 2>&1
  
* * * * * /bin/bash -x /opt/log_error_script/SDB/SDB_error_monit.sh >/dev/null 2>&1
* * * * * sleep 30;/bin/bash -x /opt/log_error_script/SDB/SDB_error_monit.sh >/dev/null 2>&1

邮件报警效果如下:

在这里插入图片描述

如上可以看出,SDB系统的任务日志里发现了error信息,现在去日志列表目录里查看下,发现出现error信息的任务日志已经拷贝到列表目录里了。
当下次脚本执行,搜索到这些日志发现error时就会去做判断,判断这些日志是否存在列表目录里,如果出现,就不会再次发出报警。

[root@bigdata-etl01 ~]# ll /opt/log_error_script/SDB/error_log/
total 12
-rw-r--r-- 1 root root 1978 Jul  6 10:36 SDB_QCX_CUSTOMER_INFO_20180705[1][1].73.log
-rw-r--r-- 1 root root 1939 Jul  6 10:19 SDB_QCX_FTTYPE_STC_20180705[1][1].51.log
-rw-r--r-- 1 root root 1939 Jul  6 10:19 SDB_QCX_SETTLE_STC_20180705[1][1].17.log

基于Ping和Telnet/NC的监控脚本案例分析

通过shell脚本,判断172.16.60.0/24网络里,当前在线的ip有哪些?能ping通则认为在线。

[root@python2 ~]# cat /tmp/ip.sh
#!/bin/bash
 
for i in $(seq 1 254)                  #这一行或者换成"for i in {1..254}"
do
  IP=172.16.60.${i}
  ping -c2 ${IP} >/dev/null 2>&1
  if [ $? = 0 ];then
    echo "${IP} is online!"
  else
    echo "${IP} is failed"
  fi
done
 
执行脚本:
[root@python2 ~]# sh /tmp/ip.sh
172.16.60.1 is online!
172.16.60.2 is failed
172.16.60.3 is failed
172.16.60.4 is failed
......

案例一:单纯地对某些ip进行ping监控

[root@test opt]# cat /opt/hosts_ip_list
192.168.10.10
192.168.10.11
192.168.10.12
192.168.10.13
192.168.10.14
192.168.10.15
192.168.10.16
192.168.10.17
 
[root@test opt]# cat /opt/hosts_ip_monit.sh
#!/bin/bash
for ip in $(cat /opt/hosts_ip_list)  
  do
     ping -c 1 $ip &>/dev/null                      #ping 3次,当3次ping都失败时,则判定此ip网络通信失败。
     a=$?
     sleep 2
     ping -c 1 $ip &>/dev/null
     b=$?
     sleep 2
     ping -c 1 $ip &>/dev/null
     c=$?
     sleep 2
     DATE=$(date +%F" "%H:%M)
     if [ $a -ne 0 -a $b -ne 0 -a $c -ne 0 ];then
         echo -e "Date : $DATE\nHost : $ip\nProblem : Ping is failed."
         /bin/sed -i 's/^'$ip'/'#$ip'/g' /etc/hosts
     else
         echo "$ip ping is successful."
        /bin/sed -i 's/^'#$ip'/'$ip'/g' /etc/hosts
     fi
done
 
[root@test opt]# chmod 755 /opt/hosts_ip_monit.sh
 
[root@test opt]# sh /opt/hosts_ip_monit.sh
Date : 2018-04-24 15:49
Host : 192.168.10.10
Problem : Ping is failed.
Date : 2018-04-24 15:50
Host : 192.168.10.11
Problem : Ping is failed.
192.168.10.12 ping is successful.
192.168.10.13 ping is successful.
192.168.10.14 ping is successful.
192.168.10.15 ping is successful.
192.168.10.16 ping is successful.
Date : 2018-04-24 15:51
Host : 192.168.10.17
Problem : Ping is failed.

案例二:对/etc/hosts列表里的ip映射关系进行ping监控报警

测试系统服务器需要访问域名www.test.com,该域名解析的DNS地址有很多个,需要在测试系统服务器上的做host绑定。在/etc/hosts文件了做了www.test.com域名的很多绑定,
在域名解析时,会从host绑定配置里从上到下匹配,如果上面绑定的ip不通,则域名解析就会失败,不会主动去解析到下一个绑定的地址,除非将这个不通的ip绑定注释掉或删除掉。
 
现在要求:
当/etc/hosts文件里绑定的ip出现故障,ping不通的时候,将该ip的绑定自动注释,并发出邮件报警;如果该ip恢复了正常通信,将自动打开该ip的绑定设置。
  
[root@cx-app01 ~]# cat /etc/hosts
#192.168.10.10 www.test.com
#192.168.10.11 www.test.com
192.168.10.12 www.test.com
192.168.10.13 www.test.com
192.168.10.14 www.test.com
192.168.10.15 www.test.com
192.168.10.16 www.test.com
#192.168.10.17 www.test.com
  
[root@cx-app01 ~]# ping www.test.com
PING www.test.com (192.168.10.12) 56(84) bytes of data.
64 bytes from www.test.com (192.168.10.12): icmp_seq=1 ttl=50 time=31.1 ms
64 bytes from www.test.com (192.168.10.12): icmp_seq=2 ttl=50 time=30.7 ms
64 bytes from www.test.com (192.168.10.12): icmp_seq=3 ttl=50 time=30.8 ms
.......
  
[root@cx-app01 ~]# cat /opt/hosts_ip_list
192.168.10.10
192.168.10.11
192.168.10.12
192.168.10.13
192.168.10.14
192.168.10.15
192.168.10.16
192.168.10.17
  
[root@cx-app01 ~]# cat /opt/hosts_ip_monit.sh
#!/bin/bash
for ip in $(cat /opt/hosts_ip_list) 
  do
     ping -c 1 $ip &>/dev/null        
     a=$?
     sleep 2
     ping -c 1 $ip &>/dev/null
     b=$?
     sleep 2
     ping -c 1 $ip &>/dev/null
     c=$?
     sleep 2
     DATE=$(date +%F" "%H:%M)
     if [ $a -ne 0 -a $b -ne 0 -a $c -ne 0 ];then
         echo -e "Date : $DATE\nHost : $ip\nProblem : Ping is failed."
         cat /etc/hosts|grep "^#$ip"
         d=$?
           if [ $d -ne 0 ];then
              /bin/bash /opt/sendemail.sh zhangsan@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip连接失败,现已在/etc/hosts文件里注释掉该ip的映射关系"
              /bin/bash /opt/sendemail.sh lisi@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip连接失败,现已在/etc/hosts文件里注释掉该ip的映射关系"
              /bin/bash /opt/sendemail.sh liuwu@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip连接失败,现已在/etc/hosts文件里注释掉该ip的映射关系"
              /bin/sed -i 's/^'$ip'/'#$ip'/g' /etc/hosts
           else
              echo "$ip is not conneted,and it has been done"
           fi
     else
         echo "$ip ping is successful."
         cat /etc/hosts|grep "^#$ip"
         f=$?
           if [ $f -eq 0 ];then
              /bin/bash /opt/sendemail.sh zhangsan@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip连接成功,现已在/etc/hosts文件里恢复该ip的映射关系"
              /bin/bash /opt/sendemail.sh lisi@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip连接成功,现已在/etc/hosts文件里恢复该ip的映射关系"
              /bin/bash /opt/sendemail.sh liuwu@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip连接成功,现已在/etc/hosts文件里恢复该ip的映射关系"
              /bin/sed -i 's/^'#$ip'/'$ip'/g' /etc/hosts
           else
              echo "$ip connection has been restored"
           fi
     fi
done
  
  
采用sendemail进行邮件告警发送,sendemail部署参考:http://www.cnblogs.com/kevingrace/p/5961861.html
[root@cx-app01 ~]# cat /opt/sendemail.sh
#!/bin/bash
# Filename: SendEmail.sh
# Notes: 使用sendEmail
#
# 脚本的日志文件
LOGFILE="/tmp/Email.log"
:>"$LOGFILE"
exec 1>"$LOGFILE"
exec 2>&1
SMTP_server='smtp.test.com'
username='monit@test.com'
password='monit@123'
from_email_address='monit@test.com'
to_email_address="$1"
message_subject_utf8="$2"
message_body_utf8="$3"
# 转换邮件标题为GB2312,解决邮件标题含有中文,收到邮件显示乱码的问题。
message_subject_gb2312=`iconv -t GB2312 -f UTF-8 << EOF
$message_subject_utf8
EOF`
[ $? -eq 0 ] && message_subject="$message_subject_gb2312" || message_subject="$message_subject_utf8"
# 转换邮件内容为GB2312,解决收到邮件内容乱码
message_body_gb2312=`iconv -t GB2312 -f UTF-8 << EOF
$message_body_utf8
EOF`
[ $? -eq 0 ] && message_body="$message_body_gb2312" || message_body="$message_body_utf8"
# 发送邮件
sendEmail='/usr/local/bin/sendEmail'
set -x
$sendEmail -s "$SMTP_server" -xu "$username" -xp "$password" -f "$from_email_address" -t "$to_email_address" -u "$message_subject" -m "$message_body" -o message-content-type=text -o message-charset=gb2312
  
  
每10分钟定时执行该监控脚本
[root@cx-app01 ~]# crontab -l
*/10 * * * *  /bin/bash -x /opt/hosts_ip_monit.sh > /dev/null 2>&1

案例三:通过nc工具对/etc/hosts列表里的ip的443端口跟本机通信是否正常进行探测

案例二是针对ping编写的监控脚本,下面介绍下利用nc探测端口通信是否正常的脚本:
 
探测本机对下面/etc/hosts文件里的ip地址的443端口通信是否正常,如果通信失败,则发出报警,并在/etc/hosts文件里注释掉该ip地址的绑定关系。
如果注释掉的ip的443端口跟本机恢复了通信,则去掉/etc/hosts文件里该ip的注释!
 
[root@cx-app01 ~]# cat /etc/hosts
192.168.10.201 www.test.com
192.168.10.205  www.test.com
192.168.10.17  www.test.com
192.168.10.85  www.test.com
192.168.10.176   www.test.com
192.168.10.245  www.test.com
192.168.10.25    www.test.com
192.168.10.47  www.test.com
 
[root@cx-app01 ~]# cat /opt/hosts_ip_list
192.168.10.201
192.168.10.205
192.168.10.17
192.168.10.85
192.168.10.176
192.168.10.245
192.168.10.25
192.168.10.47
 
采用nc工具去探测端口是否正常通信(yum install -y nc)
[root@cx-app01 ~]# /usr/bin/nc -z  -w 10 192.168.10.201 443
Connection to 192.168.10.201 443 port [tcp/https] succeeded!
 
针对上面ip列表里的地址,进行批量ip的443端口通信的探测。脚本如下:
[root@cx-app01 ~]# cat /opt/host_ip_nc_monit.sh
#!/bin/bash
for ip in $(cat /opt/hosts_ip_list) 
do
    echo -e "Date : $DATE\nHost : $ip\nProblem : Port 443 is connected."
    cat /etc/hosts|grep "^#$ip"
    a=$?
    if [ $a -ne 0 ];then
       /usr/bin/nc -z  -w 10 $ip 443
       b=$?
       if [ $b -ne 0 ];then
          /bin/bash /opt/sendemail.sh wangshibo@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip的443端口连接失败,现已在/etc/hosts文件里注释掉该ip的映射关系"
          /bin/bash /opt/sendemail.sh linan@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip的443端口连接失败,现已在/etc/hosts文件里注释掉该ip的映射关系"
          /bin/sed -i 's/^'$ip'/'#$ip'/g' /etc/hosts
       else
       echo "$HOSTNAME跟$ip的443端口正常连接"
       fi
    else
       /usr/bin/nc -z  -w 10 $ip 443
       c=$?
       if [ $c -eq 0 ];then
         /bin/bash /opt/sendemail.sh wangshibo@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip的443端口连接成功,现已在/etc/hosts文件里恢复该ip的映射关系"
         /bin/bash /opt/sendemail.sh linan@test.com "测试系统跟www.test.com通信情况" "$HOSTNAME跟$ip的443端口连接成功,现已在/etc/hosts文件里恢复该ip的映射关系"
         /bin/sed -i 's/^'#$ip'/'$ip'/g' /etc/hosts
       else
         echo "$HOSTNAME跟$ip的443端口连接失败"
       fi
    fi
done
 
给脚本赋权
[root@cx-app01 ~]# chmod 755 /opt/host_ip_nc_monit.sh
 
执行脚本:
[root@cx-app01 ~]# sh /opt/host_ip_nc_monit.sh
Date :
Host : 192.168.10.201
Problem : Port 443 is connected.
Connection to 192.168.10.201 443 port [tcp/https] succeeded!
cx-app01.veredholdings.cn跟192.168.10.201443端口正常连接
Date :
Host : 192.168.10.205
Problem : Port 443 is connected.
Connection to 192.168.10.205 443 port [tcp/https] succeeded!
cx-app01.veredholdings.cn跟192.168.10.205443端口正常连接
Date :
Host : 192.168.10.17
Problem : Port 443 is connected.
Connection to 192.168.10.17 443 port [tcp/https] succeeded!
cx-app01.veredholdings.cn跟192.168.10.17443端口正常连接
Date :
Host : 192.168.10.85
Problem : Port 443 is connected.
Connection to 192.168.10.85 443 port [tcp/https] succeeded!
cx-app01.veredholdings.cn跟192.168.10.85443端口正常连接
Date :
Host : 192.168.10.176
Problem : Port 443 is connected.
Connection to 192.168.10.176 443 port [tcp/https] succeeded!
cx-app01.veredholdings.cn跟192.168.10.176443端口正常连接
Date :
Host : 192.168.10.245
Problem : Port 443 is connected.
Connection to 192.168.10.245 443 port [tcp/https] succeeded!
cx-app01.veredholdings.cn跟192.168.10.245443端口正常连接
Date :
Host : 192.168.10.25
Problem : Port 443 is connected.
Connection to 192.168.10.25 443 port [tcp/https] succeeded!
cx-app01.veredholdings.cn跟192.168.10.25443端口正常连接
Date :
Host : 192.168.10.47
Problem : Port 443 is connected.
Connection to 192.168.10.47 443 port [tcp/https] succeeded!
cx-app01.veredholdings.cn跟192.168.10.47443端口正常连接
 
结合crontab进行计划任务
[root@cx-app01 ~]# crontab -l
*/10 * * * *  /bin/bash -x /opt/host_ip_nc_monit.sh > /dev/null 2>&1

监控磁盘的监控脚本

[root@ceph-node1 ~]# cat disk_monit.sh
#!/bin/bash
#filename:Monitor_Disk
Monitor_Disk(){
mkdir -p /mnt/Monitor_Disk
fdisk -l|grep "Disk /dev/" | awk '{print $2,$3$4}'|tr -d ',:'>/mnt/Monitor_Disk/device_list.log
N=1;ECHO 90
while read device_line
do
Device=`echo $device_line|awk '{print $1}'`
Sum=`echo $device_line|awk '{print $2}'`
df -h |grep "$Device"|sort>/mnt/Monitor_Disk/${N}_partitions.log
echo
echo "** 第$N块硬盘($Device):${Sum} **"| grep -E "$Device|$Sum|$N" --color=yes
echo "------------------------------------"
echo -e "linux分区 挂载目录 总大小 已用 剩余 已用百分比 文件系统 ID system  \
块大小  预留空间  ">/mnt/Monitor_Disk/${N}_Over.log
echo -e "========= ======== =====  ===  ===  ==========  ======= == ======  \
======  ======== ">>/mnt/Monitor_Disk/${N}_Over.log
Num_Partition=`cat /mnt/Monitor_Disk/${N}_partitions.log|wc -l`
n=0
while read partition_line
do
    Partition_Name=`echo $partition_line|awk '{print $1}'`
    Mount_Dir=`echo $partition_line|awk '{print $6}'`
    Partition_Sum=`echo $partition_line|awk '{print $2}'`
    Partition_Used=`echo $partition_line|awk '{print $3}'`
    Partition_Leave=`echo $partition_line| awk '{print $4}'`
    Partition_Percent=`echo $partition_line|awk '{print $5}'`
    Partition_Type=`mount|grep $Partition_Name|awk '{print $5$6}'`
    Partition_Id=`fdisk -l | grep $Partition_Name|tr -d '\*'|awk '{print $5}'`
    Partition_System=`fdisk -l | grep $Partition_Name|tr -d '\*'|awk '{print $6}'`
    Part_Block_Size_B=`tune2fs -l $Partition_Name|grep "Block size"|awk '{print $3}'`
    Part_Lift_For_Root_Blocks=`tune2fs -l $Partition_Name|grep "Reserved block count:"|\
    awk '{print $4}'`
    Part_Block_Size=`echo $Part_Block_Size_B/1024|bc`
    Part_Lift_For_Root=`echo ${Part_Lift_For_Root_Blocks}*${Part_Block_Size}/1024|bc`
    echo -e "$Partition_Name $Mount_Dir $Partition_Sum $Partition_Used $Partition_Leave \
$Partition_Percent $Partition_Type  $Partition_Id $Partition_System  \
${Part_Block_Size}K ${Part_Lift_For_Root}M">>/mnt/Monitor_Disk/${N}_Over.log
    let n++
 
    [ $n -eq $Num_Partition ]&&(cat /mnt/Monitor_Disk/${N}_Over.log|column -t;echo)
done</mnt/Monitor_Disk/${N}_partitions.log
let N++
done</mnt/Monitor_Disk/device_list.log
ECHO 90
rm -fr /mnt/Monitor_Disk
}
ECHO(){
for ((i=1;i<=$1;i++))
do
echo -n "#"
[ $i -eq $1 ]&&(echo;echo)
done
}
Monitor_Disk
 
 
[root@ceph-node1 ~]# chmod 755 disk_monit.sh
[root@ceph-node1 ~]# sh disk_monit.sh
##########################################################################################
 
 
**1块硬盘(/dev/sdb):577.4GB **
------------------------------------
linux分区  挂载目录  总大小  已用  剩余  已用百分比  文件系统  ID  system  块大小  预留空间
=========  ========  =====   ===   ===   ==========  =======   ==  ======  ======  ========
/dev/sdb1  /data     530G    42G   461G  9%          ext4(rw)  83  Linux   4K      27532M
 
 
**2块硬盘(/dev/sda):322.1GB **
------------------------------------
linux分区  挂载目录  总大小  已用  剩余  已用百分比  文件系统  ID  system  块大小  预留空间
=========  ========  =====   ===   ===   ==========  =======   ==  ======  ======  ========
/dev/sda1  /boot     283M    76M   193M  29%         ext4(rw)  83  Linux   1K      15M
/dev/sda3  /         265G    3.1G  248G  2%          ext4(rw)  83  Linux   4K      13744M
 
##########################################################################################

监控磁盘IO使用率的脚本,实时查看IO使用情况,防止因为磁盘IO效率低而导致MySQL查询慢的问题

#!/bin/bash
#监控磁盘IO使用率并告警

#定义收件人邮箱
mail="/usr/local/sbin/mail.py"
mail_user=admin@admin.com

if ! which iostat &>/dev/null
then
    yum install -y sysstat
fi

if ! which iotop &>/dev/null
then
    yum install -y iotop
fi

logdir=/data/iolog

dt=`date +%F`           #以日期作为日志名字

#获取IO,取5次平均值
get_io()
{
    iostat -dx 1 5 > $logdir/iostat.log
    sum=0
    
    for ut in `grep "^$1" $logdir/iostat.log |awk '{print $NF}' |cut -d '.' -f 1`
    do
        sum=$[$sum+$ut]
    done
    echo $[$sum/5]
}

while ture
do
    for d in `iostat -dx |egrep -v '^$|Device:|CPU\}' |awk '{print $1}'
    do
        io=`get_io $d`
        
        if [ $io -gt 90 ]
        then
            date >> $logdir/$dt
            cat $logdir/iostat.log >> $logdir/$dt
            iotop -obn2 >> $logdir/$dt
            echo "###################" >> $logdir/$dt
            
            python $mail $mail_user "磁盘IO使用率超过90%" "`cat $logdir/$dt`" 2>/dev/null
        fi
    done
    sleep 10
done

实时监控网卡流量的通用脚本

[root@ceph-node1 ~]# cat /root/net_monit.sh
#!/bin/bash
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin;
export PATH
function traffic_monitor {
 
  OS_NAME=$(sed -n '1p' /etc/issue)
 
  eth=$1
 
  if [ ! -d /sys/class/net/$eth ];then
      echo -e "Network-Interface Not Found"
      echo -e "You system have network-interface:\n`ls /sys/class/net`"
      exit 5
  fi
  while [ "1" ]
  do
    
    STATUS="fine"
   
    RXpre=$(cat /proc/net/dev | grep $eth | tr : " " | awk '{print $2}')
    TXpre=$(cat /proc/net/dev | grep $eth | tr : " " | awk '{print $10}')
 
    sleep 1
    RXnext=$(cat /proc/net/dev | grep $eth | tr : " " | awk '{print $2}')
    TXnext=$(cat /proc/net/dev | grep $eth | tr : " " | awk '{print $10}')
    clear
  
    RX=$((${RXnext}-${RXpre}))
    TX=$((${TXnext}-${TXpre}))
 
    if [[ $RX -lt 1024 ]];then
      RX="${RX}B/s"
    elif [[ $RX -gt 1048576 ]];then
      RX=$(echo $RX | awk '{print $1/1048576 "MB/s"}')
      $STATUS="busy"
    else
      RX=$(echo $RX | awk '{print $1/1024 "KB/s"}')
    fi
 
    if [[ $TX -lt 1024 ]];then
      TX="${TX}B/s"
      elif [[ $TX -gt 1048576 ]];then
      TX=$(echo $TX | awk '{print $1/1048576 "MB/s"}')
    else
      TX=$(echo $TX | awk '{print $1/1024 "KB/s"}')
    fi
   
    echo -e "==================================="
    echo -e "Welcome to Traffic_Monitor stage"
    echo -e "version 1.0"
    echo -e "Since 2018.7.2"
    echo -e "Created by wangshibo"
    echo -e "BLOG: http://www.cnblogs.cn/kevingrace"
    echo -e "==================================="
    echo -e "System: $OS_NAME"
    echo -e "Date:   `date +%F`"
    echo -e "Time:   `date +%k:%M:%S`"
    echo -e "Port:   $1"
    echo -e "Status: $STATUS"
    echo -e  " \t     RX \tTX"
    echo "------------------------------"
    
    echo -e "$eth \t $RX   $TX "
    echo "------------------------------"
 
    echo -e "Press 'Ctrl+C' to exit"
  done
}
 
if [[ -n "$1" ]];then
  traffic_monitor $1
else
  echo -e "None parameter,please add system netport after run the script! \nExample: 'sh traffic_monitor eth0'"
fi
 
 
 
[root@ceph-node1 ~]# chmod 755 /root/net_monit.sh
[root@ceph-node1 ~]# sh /root/net_monit.sh eth0               #eth0是网卡设备名称,如果是网卡绑定bond0,后面就跟bond0
===================================
Welcome to Traffic_Monitor stage
version 1.0
Since 2018.7.2
Created by wangshibo
BLOG: http://www.cnblogs.cn/kevingrace
===================================
System: CentOS release 6.9 (Final)
Date:   2018-07-02
Time:   15:19:34
Port:   eth0
Status: fine
        RX  TX
------------------------------
eth0   417B/s   390B/s
------------------------------
Press 'Ctrl+C' to exit
===================================
Welcome to Traffic_Monitor stage
version 1.0
Since 2018.7.2
Created by wangshibo
BLOG: http://www.cnblogs.cn/kevingrace
===================================
System: CentOS release 6.9 (Final)
Date:   2018-07-02
Time:   15:19:35
Port:   eth0
Status: fine
        RX  TX
------------------------------
eth0   1.49902KB/s   1.3252KB/s
------------------------------
Press 'Ctrl+C' to exit

检测网卡流量,并按规定格式记录在日志中

#!/bin/bash
#######################################################
#检测网卡流量,并按规定格式记录在日志中#规定一分钟记录一次
#日志格式如下所示:
#2019-08-12 20:40
#ens33 input: 1234bps
#ens33 output: 1235bps
######################################################3
while :
do
#设置语言为英文,保障输出结果是英文,否则会出现bug
LANG=en
logfile=/tmp/`date +%d`.log
#将下面执行的命令结果输出重定向到logfile日志中
exec >> $logfile
date +"%F %H:%M"
#sar命令统计的流量单位为kb/s,日志格式为bps,因此要*1000*8
sar -n DEV 1 59|grep Average|grep ens33|awk '{print $2,"\t","input:","\t",$5*1000*8,"bps","\n",$2,"\t","output:","\t",$6*1000*8,"bps"}'
echo "####################"
#因为执行sar命令需要59秒,因此不需要sleep
done

指定时间内网站访问次数的监控

需求说明:
在日常运维工作中,为了防止一些恶意访问的行为,例如不断的请求刷流量,通过实时过滤Nginx访问日志,将单位时间内访问次数达到指定阀值的来源ip查找出来,并通过邮件报警方式及时通知运维人员!

比如针对url为http://192.168.10.202:8888的访问进行监控,当在1分钟内访问次数超过300次数,就邮件报警给运维人员。

nginx日志监控脚本

[root@Fastdfs_storage_s1 ~]# cat /opt/nginx_log_monit.sh
#!/bin/bash
#日志文件
logfile=/usr/local/nginx/logs/access.log
   
#开始时间
start_time=`date -d"$last_minutes minutes ago" +"%H:%M:%S"`
   
#结束时间
stop_time=`date +"%H:%M:%S"`
   
#过滤出单位之间内的日志并统计最高ip数
tac $logfile | awk -v st="$start_time" -v et="$stop_time" '{t=substr($4,RSTART+14,21);if(t>=st && t<=et) {print $0}}' \
| awk '{print $1}' | sort | uniq -c | sort -nr > /root/log_ip_top10
ip_top=`cat /root/log_ip_top10 | head -1 | awk '{print $1}'`
# 单位时间[1分钟]内单ip访问次数超过300次,则触发邮件报警
if [[ $ip_top -gt 300 ]];then
 /usr/bin/python /opt/send_mail.py &
fi

python报警脚本

[root@Fastdfs_storage_s1 ~]# cat /opt/send_mail.py
# -*- coding: utf-8 -*-
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from datetime import datetime
import os
import smtplib
def _format_addr(s):
 name, addr = parseaddr(s)
 return formataddr((Header(name, 'utf-8').encode(), addr))
# 邮箱定义
smtp_server = 'smtp.kevin.com'
smtp_port = 465
from_addr = 'monit@kevin.com'
password = os.environ.get('monit@123')
to_addr = ['wangshibo@kevin.com']
# 邮件对象
msg = MIMEMultipart()
msg['From'] = _format_addr('发件人 <%s>' % from_addr)
msg['To'] = _format_addr('收件人 <%s>' % to_addr)
msg['Subject'] = Header('Warning:单ip请求次数异常', 'utf-8').encode()
# 获取系统中要发送的文本内容
with open('/root/log_ip_top10', 'r') as f:
 line = f.readline().strip()
 line = line.split(" ")
print(line)
# 邮件正文是MIMEText:
html = '<html><body><h2>一分钟内单ip请求次数超过阀值</h2>' + \
 '<p>ip:%s  请求次数/min:%s</p>' % (line[1],line[0]) + \
 '</body></html>'
msg.attach(MIMEText(html, 'html', 'utf-8'))
server = smtplib.SMTP_SSL(smtp_server, smtp_port)
server.login(from_addr, password)
server.sendmail(from_addr, to_addr, msg.as_string())
server.quit()

写个测试脚本不停curl请求资源触发报警

[root@Fastdfs_storage_s1 ~]# cat /opt/curl.sh
#!/bin/bash
#example:curl.sh http://www.kevin.com 100
usage()
{
 echo "usage: `basename $0` url count"
}
if [ $# -ne 2 ]; then
 usage
 exit 1
fi
for i in `seq 1 $2`;do
 http_code=`curl -o /dev/null -s -w %{http_code} $1`
 echo $1 $http_code
done
 
 
手动执行测试脚本
[root@Fastdfs_storage_s1 ~]# /bin/bash /opt/curl.sh http://192.168.10.202:8888 300
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
...........

定时任务,由于上面脚本是监控一分钟内的日志,因此每分钟执行一次

[root@Fastdfs_storage_s1 ~]# crontab -e
* * * * * /bin/bash -x /opt/nginx_log_monit.sh >/dev/null 2>&1

这里仅仅是实现了邮件告警功能,实际上还可以实现自动屏蔽恶意访问的ip。
可以通过Nginx deny来实现,也可以通过iptables屏蔽("iptables -I INPUT -s x.x.x.x -j DROP"方式)

网站访问状态和超时时间监控报警设置

对网站访问状态和超时时间进行监控:当code状态为5xx或者访问超时时间大于10s时进行报警。脚本脚本如下:

[root@qd-inf-logcollector01 web_monit]$ pwd
/app/script/web_monit
 
[root@qd-inf-logcollector01 web_monit]$ ll
total 12
-rwxr-xr-x 1 root root 870 Oct 12 21:34 http_monit.sh      //监控脚本
-rwxr-xr-x 1 root root 857 Oct 12 21:25 sms.py             //短信报警脚本,里面有报警联系人            
-rw-r--r-- 1 root root 377 Oct 12 21:27 weblist.txt        //监控的网站域名列表
 
[root@qd-inf-logcollector01 web_monit]$ cat http_monit.sh
#!/bin/sh
weblist=/app/script/web_monit/weblist.txt                      
for list in `cat $weblist|grep -E -v "#|^$"`               
do
httpcode=`curl -o /dev/null -s -w %{http_code} "$list"`        
httptime=`curl -o /dev/null -s -w "time_connect: %{time_connect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" "$list"|grep time_total|awk -F ":" '{print $2*1000}'`
if [ $httpcode = 500 ]||[ $httpcode = 502 ]||[ $httpcode = 503 ]||[ $httpcode = 504 ]
then
   python /app/script/web_monit/sms.py $list "$list 访问有误!状态码为$httpcode!请收到报警后尽快查看并处理!"
else
   echo "$list is checked ok!"
fi
 
if [ $httptime -ge 10000 ]
then
   python /app/script/web_monit/sms.py $list " $list访问超时!超时时间为$httptime毫秒!请收到报警后尽快查看并处理!"
else
  echo "$list is connect ok!"
fi
done

手动检查网站访问的code状态码

[root@qd-inf-logcollector01 web_monit]$ curl -o /dev/null -s -w %{http_code} http://www.wang.com
200

手动检查网站访问的超时时间(单位:毫秒,如下网址访问的时间为0.8秒)

[root@qd-inf-logcollector01 web_monit]$ curl -o /dev/null -s -w "time_connect: %{time_connect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n" http://www.wang.com |grep time_total|awk -F ":" '{print $2*1000}'
800

网站列表和脚本执行

[root@qd-inf-logcollector01 web_monit]$cat weblist.txt
http://nop.kevin.cn
http://ap.kevin.cn
http://ope.kevin.cn
http://opr.kevin.cn
http://www.kevin.cn
http://kevin.cn
http://tb.kevin.cn
http://www.wang.com
https://www.wang.com
 
http://doc.kevin.cn
http://docs.kevin.cn
http://git.wang.com
http://monitor.kevin.cn
http://dash.kevin.cn
 
[root@qd-inf-logcollector01 web_monit]$sh http_monit.sh
http://nop.kevin.cn is checked ok!
http://nop.kevin.cn is connect ok!
http://ap.kevin.cn is checked ok!
http://ap.kevin.cn is connect ok!
http://ope.kevin.cn is checked ok!
http://ope.kevin.cn is connect ok!
http://opr.kevin.cn is checked ok!
http://opr.kevin.cn is connect ok!
http://www.kevin.cn is checked ok!
http://www.kevin.cn is connect ok!
http://kevin.cn is checked ok!
http://kevin.cn is connect ok!
http://tb.kevin.cn is checked ok!
http://tb.kevin.cn is connect ok!
http://www.wang.com is checked ok!
http://www.wang.com is connect ok!
https://www.wang.com is checked ok!
https://www.wang.com is connect ok!
http://doc.kevin.cn is checked ok!
http://doc.kevin.cn is connect ok!
http://docs.kevin.cn is checked ok!
http://docs.kevin.cn is connect ok!
http://git.wang.com is checked ok!
http://git.wang.com is connect ok!
http://monitor.kevin.cn is checked ok!
http://monitor.kevin.cn is connect ok!
http://dash.kevin.cn is checked ok!
http://dash.kevin.cn is connect ok!

定时监控任务(每两分钟监控一次)

[root@qd-inf-logcollector01 web_monit]$ crontab -l
*/2 * * * * /bin/bash -x /app/script/web_monit/http_monit.sh  > /dev/null 2>&1

简单注意下:比较运算符只有==和!=是用于字符串比较的,不可用于整数比较;整数比较只能使用-eq, -gt这种形式

服务器磁盘监控脚本(含报警邮件)

在日常的运维工作中,我们经常会对服务器的磁盘使用情况进行巡检,以防止磁盘爆满导致的业务故障。如果能编写一个合理完善的监控脚本,当磁盘使用率达到我们设置的阀值时,就自动发送报警邮件,以便我们及时获悉到快爆满的磁盘情况!

下面分享一个脚本:
监控本机的根磁盘和home盘,当根磁盘使用率达到90%和home磁盘使用率达到95%的时候,发报警邮件至wangshibo@kevin.cn和liugang@kevin.cn

[root@kevin ~]# df -h
Filesystem                    Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root   50G   46G   12G  90% /
tmpfs                          32G   68K   32G   1% /dev/shm
/dev/sda1                     485M   40M  421M   9% /boot
/dev/mapper/VolGroup-lv_home  836G  795G  673G  95% /home
 
取根磁盘当前利用率的百分值
[root@kevin ~]# /bin/df -h|grep /dev/mapper/VolGroup-lv_root|awk -F" " '{print $5}'|cut -d"%" -f1
90
 
取home盘当前利用率的百分值
[root@kevin ~]# /bin/df -h|grep /dev/mapper/VolGroup-lv_home|awk -F" " '{print $5}'|cut -d"%" -f1
95
 
编写邮件报警脚本
[root@kevin ~]# vim /root/root_disk.sh
#!/bin/bash
SERVER_IP=`ifconfig|grep 192.168.1|awk -F":" '{print $2}'|cut -d" " -f1`
ROOT_DISK=`/bin/df -h|grep /dev/mapper/VolGroup-lv_root|awk -F" " '{print $5}'|cut -d"%" -f1`
HOME_DISK=`/bin/df -h|grep /dev/mapper/VolGroup-lv_home|awk -F" " '{print $5}'|cut -d"%" -f1`
 
if [ $ROOT_DISK -ge 90 ];then
/usr/local/bin/sendEmail -f ops@kevin.cn -t wangshibo@kevin.cn -s smtp.kevin.cn -u " The ROOT_DISK of $SERVER_IP-$HOSTNAME is warning!" -o message-content-type=html -o message-charset=utf8 -xu ops@kevin.cn -xp zh@123bj -m "The ROOT_DISK of $SERVER_IP-$HOSTNAME,now use% is 90%,please deal with it as soon as possible"
/usr/local/bin/sendEmail -f ops@kevin.cn -t liugang@kevin.cn -s smtp.kevin.cn -u " The ROOT_DISK of $SERVER_IP-$HOSTNAME is warning!" -o message-content-type=html -o message-charset=utf8 -xu ops@kevin.cn -xp zh@123bj -m "The ROOT_DISK of $SERVER_IP-$HOSTNAME,now use% is 90%,please deal with it as soon as possible"
else
echo "The ROOT_DISK of $SERVER_IP-$HOSTNAME is Enough to use"
fi
 
sleep 5
 
if [ $HOME_DISK -ge 95 ];then
/usr/local/bin/sendEmail -f ops@kevin.cn -t wangshibo@kevin.cn -s smtp.kevin.cn -u " The HOME_DISK of $SERVER_IP-$HOSTNAME is warning!" -o message-content-type=html -o message-charset=utf8 -xu ops@kevin.cn -xp zh@123bj -m "The HOME_DISK of $SERVER_IP-$HOSTNAME,now use% is 95%,please deal with it as soon as possible"
/usr/local/bin/sendEmail -f ops@kevin.cn -t liugang@kevin.cn -s smtp.kevin.cn -u " The HOME_DISK of $SERVER_IP-$HOSTNAME is warning!" -o message-content-type=html -o message-charset=utf8 -xu ops@kevin.cn -xp zh@123bj -m "The HOME_DISK of $SERVER_IP-$HOSTNAME,now use% is 95%,please deal with it as soon as possible"
else
echo "The ROOT_DISK of $SERVER_IP-$HOSTNAME is Enough to use"
fi
 
===============================================================
设置计划任务
[root@kevin ~]# crontab -e
*/30 * * * * /bin/bash -x /root/root_disk.sh > /dev/null 2>&1

在这里插入图片描述
上面脚本中的邮件报警用的是sendemail,需要提前安装sendemail环境,安装操作如下:

1)先下载安装包到本地,解压。
[root@kevin ~]# cd /usr/local/src/
[root@kevin src]# wget -c http://caspian.dotconf.net/menu/Software/SendEmail/sendEmail-v1.56.tar.gz
[root@kevin src]# tar -zvxf sendEmail-v1.56.tar.gz
[root@kevin src]# cd sendEmail-v1.56
[root@kevin sendEmail-v1.56]# cp -a sendEmail /usr/local/bin/
[root@kevin sendEmail-v1.56]# chmod +x /usr/local/bin/sendEmail
[root@kevin sendEmail-v1.56]# file /usr/local/bin/sendEmail
/usr/local/bin/sendEmail: a /usr/bin/perl -w script text executable
   
2)安装下依赖
[root@kevin sendEmail-v1.56]# yum install perl-Net-SSLeay perl-IO-Socket-SSL -y
   
[root@kevin sendEmail-v1.56]# /usr/local/bin/sendEmail -f from@kevin.cn -t to@kevin.cn -s smtp.kevin.cn -u "我是邮件主题" -o message-content-type=html -o message-charset=utf8 -xu from@kevin.cn -xp zh@123bj -m "我是邮件内容"
   
命令说明:
/usr/local/bin/sendEmail                          #命令主程序
-f from@kevin.cn                                  #发件人邮箱
-t to@kevin.cn                                    #收件人邮箱
-s smtp.huanqi.cn                                 #发件人邮箱的smtp服务器
-u "我是邮件主题"                                 #邮件的标题
-o message-content-type=html                      #邮件内容的格式,html表示它是html格式
-o message-charset=utf8                           #邮件内容编码
-xu from@kevin.cn                                 #发件人邮箱的用户名
-xp zh@123bj                                      #发件人邮箱密码
-m "我是邮件内容"                                 #邮件的具体内容
   
例如:
[root@kevin alertscripts]# /usr/local/bin/sendEmail -f ops@kevin.cn -t wangshibo@kevin.cn -s smtp.kevin.cn -u "我是邮件主题" -o message-content-type=html -o message-charset=utf8 -xu ops@kevin.cn -xp zh@123bj -m "我是邮件内容"
Oct 14 19:38:29 kevin sendEmail[65454]: Email was sent successfully!

登陆wangshibo@kevin.cn邮箱,发现已经收到了上面发送的邮件:

在这里插入图片描述

业务日志清理脚本

线上某些系统业务跑一段时间后,日志就会越来越多,考虑到业务机器磁盘有限,需要添加业务日志清理功能。根据日志所在分区磁盘使用情况来判断是否清理日志,比如当日志分区磁盘空间使用超过90%时,将一周前的日志打包转移到别处 (别的分区下或远程存储设备上)。脚本 (/opt/script/log_clear.sh) 如下:

#!/bin/bash
 
#定义日志所在分区当前空间所占比例数(去掉%)。grep -w表示精准匹配,只匹配"/"这个分区
LOG_PARTITION=$(`which df` -h|awk '{print $5,$6}'|grep -w "/"|cut -d" " -f1|awk -F"%" '{print $1}')
#定义一周前的日期,用于日志分区空间超过设定的阈值后保留的份数(这里保留一周的日志)
KEEP_DATE=`date -d '-7 days' +%Y%m%d`
#定义日志路径
LOG_DIR=/opt/log/kevin
#定义日志备份路径(即当日志分区空间超过阈值后,将日志转移到该处。这里就转移到了本地home分区下,也可以转移到别的机器或远程存储设备上)
LOG_BACK_DIR=/home/log/kevin
 
#确保日志备份路径存在,如果不存在,则创建该路径。
if [ ! -d ${LOG_BACK_DIR} ];then
   `which mkdir` -p ${LOG_BACK_DIR}
else
   echo "${LOG_BACK_DIR} is exist" >/dev/null 2>&1
fi
 
#当日志分区当前空间超过90%时执行的动作
if [ ${LOG_PARTITION} -ge 90 ];then
    
   #切换到日志路径下
   cd ${LOG_DIR}
   #截取日志文件中的日期,比如stepweb_20190915.log日志文件,则截取20190915
   for LOG_DATE in $(ls -l ${LOG_DIR}|awk '{print $9}'|cut -d"_" -f2|awk -F"." '{print $1}')
   do
     #当日志文件中截取的日期是一周之前的日志时执行的动作
     if [ ${LOG_DATE} -lt ${KEEP_DATE} ];then
       #打包,转移,删除
       #注意这里tar使用-P参数,因为tar默认为相对路径,使用绝对路径的话会报错"Removing leading `/’ from member names",使用-P参数就解决了该问题
       `which tar` -zvPcf ${LOG_DIR}/stepweb_${LOG_DATE}.log.tar.gz ${LOG_DIR}/stepweb_${LOG_DATE}.log
       mv ${LOG_DIR}/stepweb_${LOG_DATE}.log.tar.gz ${LOG_BACK_DIR}/
       rm -rf ${LOG_DIR}/stepweb_${LOG_DATE}.log
     else
       echo "keep stepweb_${LOG_DATE}.log" >/dev/null 2>&1
     fi
   done
else
   echo "${LOG_PARTITION} is available" >/dev/null 2>&1
fi

根据上面脚本验证下:

查看本机磁盘使用情况,日志所在分区磁盘当前使用率达到92%[root@yyweb kevin]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   50G  46G   4G     92% /
devtmpfs                 3.9G     0  3.9G   0% /dev
tmpfs                    3.9G     0  3.9G   0% /dev/shm
tmpfs                    3.9G   34M  3.8G   1% /run
tmpfs                    3.9G     0  3.9G   0% /sys/fs/cgroup
/dev/sda1               1014M  183M  832M  19% /boot
/dev/mapper/centos-home  142G   33M  142G   1% /home
 
日志所在路径
[root@yyweb kevin]# pwd
/opt/log/kevin
 
日志情况
[root@yyweb kevin]# ls
stepweb_20190810.log  stepweb_20190817.log  stepweb_20190824.log  stepweb_20190901.log  stepweb_20190908.log  stepweb_20190915.log
stepweb_20190811.log  stepweb_20190818.log  stepweb_20190825.log  stepweb_20190902.log  stepweb_20190909.log  stepweb_20190916.log
stepweb_20190812.log  stepweb_20190819.log  stepweb_20190826.log  stepweb_20190903.log  stepweb_20190910.log  stepweb_20190917.log
stepweb_20190813.log  stepweb_20190820.log  stepweb_20190827.log  stepweb_20190904.log  stepweb_20190911.log  stepweb_20190918.log
stepweb_20190814.log  stepweb_20190821.log  stepweb_20190828.log  stepweb_20190905.log  stepweb_20190912.log  stepweb_20190919.log
stepweb_20190815.log  stepweb_20190822.log  stepweb_20190829.log  stepweb_20190906.log  stepweb_20190913.log
stepweb_20190816.log  stepweb_20190823.log  stepweb_20190830.log  stepweb_20190907.log  stepweb_20190914.log
 
[root@yyweb kevin]# ls /home/
[root@yyweb kevin]#
 
执行日志清理脚本
[root@yyweb kevin]# sh /opt/script/log_clear.sh
/opt/log/kevin/stepweb_20190810.log
/opt/log/kevin/stepweb_20190811.log
/opt/log/kevin/stepweb_20190812.log
/opt/log/kevin/stepweb_20190813.log
/opt/log/kevin/stepweb_20190814.log
/opt/log/kevin/stepweb_20190815.log
/opt/log/kevin/stepweb_20190816.log
/opt/log/kevin/stepweb_20190817.log
/opt/log/kevin/stepweb_20190818.log
/opt/log/kevin/stepweb_20190819.log
/opt/log/kevin/stepweb_20190820.log
/opt/log/kevin/stepweb_20190821.log
/opt/log/kevin/stepweb_20190822.log
/opt/log/kevin/stepweb_20190823.log
/opt/log/kevin/stepweb_20190824.log
/opt/log/kevin/stepweb_20190825.log
/opt/log/kevin/stepweb_20190826.log
/opt/log/kevin/stepweb_20190827.log
/opt/log/kevin/stepweb_20190828.log
/opt/log/kevin/stepweb_20190829.log
/opt/log/kevin/stepweb_20190830.log
/opt/log/kevin/stepweb_20190901.log
/opt/log/kevin/stepweb_20190902.log
/opt/log/kevin/stepweb_20190903.log
/opt/log/kevin/stepweb_20190904.log
/opt/log/kevin/stepweb_20190905.log
/opt/log/kevin/stepweb_20190906.log
/opt/log/kevin/stepweb_20190907.log
/opt/log/kevin/stepweb_20190908.log
/opt/log/kevin/stepweb_20190909.log
/opt/log/kevin/stepweb_20190910.log
/opt/log/kevin/stepweb_20190911.log
/opt/log/kevin/stepweb_20190912.log
 
日志清理后,日志路径下只保留了最近一周的日志
[root@yyweb kevin]# ls
stepweb_20190913.log  stepweb_20190915.log  stepweb_20190917.log  stepweb_20190919.log
stepweb_20190914.log  stepweb_20190916.log  stepweb_20190918.log
 
一周之前的日志被打包转移到/home/log/kevin下了
[root@yyweb kevin]# ls /home/log/kevin/
stepweb_20190810.log.tar.gz  stepweb_20190817.log.tar.gz  stepweb_20190824.log.tar.gz  stepweb_20190901.log.tar.gz  stepweb_20190908.log.tar.gz
stepweb_20190811.log.tar.gz  stepweb_20190818.log.tar.gz  stepweb_20190825.log.tar.gz  stepweb_20190902.log.tar.gz  stepweb_20190909.log.tar.gz
stepweb_20190812.log.tar.gz  stepweb_20190819.log.tar.gz  stepweb_20190826.log.tar.gz  stepweb_20190903.log.tar.gz  stepweb_20190910.log.tar.gz
stepweb_20190813.log.tar.gz  stepweb_20190820.log.tar.gz  stepweb_20190827.log.tar.gz  stepweb_20190904.log.tar.gz  stepweb_20190911.log.tar.gz
stepweb_20190814.log.tar.gz  stepweb_20190821.log.tar.gz  stepweb_20190828.log.tar.gz  stepweb_20190905.log.tar.gz  stepweb_20190912.log.tar.gz
stepweb_20190815.log.tar.gz  stepweb_20190822.log.tar.gz  stepweb_20190829.log.tar.gz  stepweb_20190906.log.tar.gz
stepweb_20190816.log.tar.gz  stepweb_20190823.log.tar.gz  stepweb_20190830.log.tar.gz  stepweb_20190907.log.tar.gz

再贴一个简单的日志处理脚本

#!/usr/bin/sh
#根据系统/服务/日志保留天数三个参数压缩日志
#usage: sh clearlog.sh sysname appname keepdays
sysName=$1
appName=$2
keepDay=$3
logDir=/var/log/${sysName}/${appName}
logFile=${appName}.log
cd ${logDir}
find ./ -name "${logFile}.*[0-9][0-9]" -mtime +${keepDay} -exec gzip {} \;

Linux下间隔多少秒 (即以秒为单位) 去执行某条命令或某个shell脚本的操作方法

在日常运维工作中, 经常会碰到以秒为单位去定时执行某些命令或监控脚本的需求。 说到定时任务就要用到crontab,通常来说,crontab的最小单位是分钟级别,要想实现秒级别的定时任务,就要进行特殊设置了。

[root@test ~]# cat /root/kevin.sh
#!/bin/bash
echo "beijing is so good!" >> /root/test.log
 
添加脚本执行权限,并配置到crontab计划任务里(使用&& 或者 ;都是一样的效果)。思路:先过一分钟执行第一次,接着就是每隔2秒钟执行一次。
[root@test ~]# chmod 755 /root/kevin.sh
[root@test ~]# crontab -e
* * * * * /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 2 &&  /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 4; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 6; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 8; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 10; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 12; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 14; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 16; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 18; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 20; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 22; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 24; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 26; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 28; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 30; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 32; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 34; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 36; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 38; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 40; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 42; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 44; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 46; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 48; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 50; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 52; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 54; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 56; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
* * * * * sleep 58; /bin/bash -x /root/kevin.sh >/dev/null 2>&1
 
[root@test ~]# tail -f /root/test.log
beijing is so good!
beijing is so good!
beijing is so good!
beijing is so good!
beijing is so good!
beijing is so good!
beijing is so good!
beijing is so good!
beijing is so good!
..........
..........

Linux下批量ping某个网段ip的脚本

比如现在需要对172.16.50.0/24网段的ip进行检查,检查哪些ip现在被占用,哪些ip没有被占用,可以通过ping命令来检查,脚本如下:

[root@uatdns01 opt]# vim /opt/ping.sh
#!/bin/bash
. /etc/init.d/functions
for var in {1..254};
do
ip=172.16.50.$var
ping -c2 $ip >/dev/null 2>&1
if [ $? = 0 ];then
action "$ip" /bin/true
else
action "$ip" /bin/false
fi
done
 
[root@uatdns01 opt]# chmod 755 /opt/ping.sh
[root@uatdns01 opt]# sh /opt/ping.sh
172.16.50.1                                                [  OK  ]
172.16.50.2                                                [FAILED]
172.16.50.3                                                [FAILED]
172.16.50.4                                                [FAILED]
172.16.50.5                                                [FAILED]
.........
.........
172.16.50.99                                             [  OK  ]
172.16.50.100                                            [  OK  ]
172.16.50.101                                            [  OK  ]
172.16.50.102                                            [  OK  ]
172.16.50.103                                            [  OK  ]
172.16.50.104                                            [  OK  ]
172.16.50.105                                            [  OK  ]
172.16.50.106                                            [  OK  ]
172.16.50.107                                            [  OK  ]
172.16.50.108                                            [  OK  ]
172.16.50.109                                            [  OK  ]
172.16.50.110                                            [  OK  ]
172.16.50.111                                            [FAILED]
172.16.50.112                                            [  OK  ]
获取172.16.60.0/24网段可用ip的shell脚本
[root@ansible-server ~]# cat ip_ping.sh
#!/bin/bash
ip=1
while [ $ip != "254" ]; do
ping 172.16.60.$ip -c 2 | grep -q "ttl=" && echo "172.16.60.$ip yes" || echo "172.16.60.$ip no"
ip=`expr "$ip" "+" "1"`
done
 
执行:
[root@ansible-server ~]# sh ip_ping.sh
172.16.60.1 yes
172.16.60.2 no
172.16.60.3 no
.............
172.16.60.24 yes
172.16.60.25 yes
172.16.60.26 no
.............
 
如果只打印可用ip, 则脚本修改如下:
[root@ansible-server ~]# cat ip_ping.sh
#!/bin/bash
ip=1
while [ $ip != "254" ]; do
ping 172.16.60.$ip -c 2 | grep -q "ttl=" && echo "172.16.60.$ip yes" || echo "172.16.60.$ip no" >/dev/null 2>&1
ip=`expr "$ip" "+" "1"`
done
 
执行:
[root@ansible-server ~]# sh ip_ping.sh
172.16.60.1 yes
172.16.60.21 yes
172.16.60.22 yes
172.16.60.23 yes
172.16.60.24 yes
172.16.60.25 yes
172.16.60.31 yes
172.16.60.32 yes
172.16.60.33 yes
172.16.60.34 yes
172.16.60.35 yes
172.16.60.36 yes
172.16.60.37 yes
172.16.60.38 yes
172.16.60.39 yes
 
 
获取172.16.50.0/24, 172.16.51.0/24, 172.16.60.0/24 三个网段的可用ip
[root@ansible-server ~]# cat ip_ping.sh
#!/bin/bash
ip=1
while [ $ip != "254" ]; do
 
ping 172.16.50.$ip -c 2 | grep -q "ttl=" && echo "172.16.50.$ip yes" || echo "172.16.50.$ip no" >/dev/null 2>&1
ip=`expr "$ip" "+" "1"`
 
ping 172.16.51.$ip -c 2 | grep -q "ttl=" && echo "172.16.51.$ip yes" || echo "172.16.51.$ip no" >/dev/null 2>&1
ip=`expr "$ip" "+" "1"`
 
ping 172.16.60.$ip -c 2 | grep -q "ttl=" && echo "172.16.60.$ip yes" || echo "172.16.60.$ip no" >/dev/null 2>&1
ip=`expr "$ip" "+" "1"`
 
done
 
执行:
[root@ansible-server ~]# sh ip_ping.sh
172.16.50.1 yes
172.16.51.11 yes
172.16.50.16 yes
172.16.50.19 yes
172.16.51.20 yes
172.16.60.21 yes
172.16.50.22 yes
172.16.60.24 yes
172.16.50.25 yes
172.16.50.31 yes
172.16.60.33 yes
172.16.51.35 yes
172.16.60.36 yes
172.16.60.39 yes
172.16.51.41 yes
172.16.51.44 yes
172.16.50.52 yes
172.16.51.53 yes
172.16.50.55 yes
172.16.50.58 yes
172.16.51.65 yes
..................

查看系统运行情况

#!/bin/bash
#用于查看系统运行情况

#功能选择菜单
menu(){
        echo -e "\033[31;32m                              查看系统运行情况                                 \033[0m"
        echo -e "\033[31;32m================================================================================\033[0m"
        echo -e "\033[34m请选择:\033[0m"
        echo -e "\033[33m1、查看系统负载   2、查看CPU消耗%   3、查看内存消耗%   4、查看SWAP消耗%   \033[0m"
        echo -e "\033[33m5、查看磁盘消耗%   6、查看inode消耗%   7、查看磁盘IO   8、查看网络流量   \033[0m"
        echo -e "\033[33m9、一键查看所有情况   10、退出脚本   \033[0m"
        echo -e "\033[31;32m================================================================================\033[0m"
        echo
        read -p "请输入数字:1-8[单独查看],9[一键查看],10[退出脚本]: " num
}

#(1)查看系统负载
load_average(){
    cpu_core=`grep 'model name' /proc/cpuinfo | wc -l`
    echo -e "\033[36mCPU核数: $cpu_core\033[0m"
    
    load=`uptime |awk -F ',' '{print $3 $4 $5}' |sed 's/^ *//'`
    echo -e "\033[36m$load\033[0m"
    echo ""
}

#(2)查看CPU消耗%
cpu_use_percent(){
    cpu_idle=`vmstat |awk '{print $15}' |sed '1,2d'`
    cpu_use=$[100-$cpu_idle]
    echo -e "\033[36mCPU使用率%: $cpu_use\033[0m"
    echo ""
}

#(3)查看内存消耗%
mem_use_percent(){
    mem_used=`free -m |grep Mem |awk '{print $3}'`
    mem_tol=`free -m |grep Mem |awk '{print $2}'`
    mem_use=`awk 'BEGIN{print '$mem_used'/'$mem_tol'*100}'`
    echo -e "\033[36m内存已使用"$mem_used"M,总内存"$mem_tol"M,内存使用率%: $mem_use\033[0m"
    echo ""
}

#(4)查看SWAP消耗%
swap_use_percent(){
    swap_used=`free -m |grep Swap |awk '{print $3}'`
    swap_tol=`free -m |grep Swap |awk '{print $2}'`
    swap_use=`awk 'BEGIN{print '$swap_used'/'$swap_tol'*100}'`
    echo -e "\033[36mSwap已使用"$swap_used"M,总Swap"$swap_tol"M,Swap使用率%: $swap_use\033[0m"
    echo ""
}

#(5)查看磁盘消耗%
disk_use_percent(){
    disk_use=`df -h |sed '1d'`
    echo -e "\033[36m磁盘使用情况: \n$disk_use\033[0m"
    echo ""
}

#(6)查看inode消耗%
inode_use_percent(){
    inode_use=`df -i |sed '1d'`
    echo -e "\033[36minode使用情况: \n$inode_use\033[0m"
    echo ""
}

#(7)查看磁盘IO
disk_io(){
    disk_io_bi=`vmstat |awk '{print $9}' |sed '1,2d'`
    echo -e "\033[36m发送到块设备的块数: "$disk_io_bi"块每秒\033[0m"
    
    disk_io_bo=`vmstat |awk '{print $10}' |sed '1,2d'`
    echo -e "\033[36m从块设备接收到的块数: "$disk_io_bo"块每秒\033[0m"
    echo ""
}

#(8)查看网络流量
network_flow(){
    #安装所需命令sysstat
    if  ! rpm -q sysstat > /dev/null
    then
        yum install -y sysstat &>/dev/null
        if [ $? -ne 0 ]
        then
            echo -e "\033[31msysstat 安装失败\033[0m"
            exit 1
        fi
    fi
    explain=`sar -n DEV |sed -n '3p'`
    echo -e "\033[35m网络流量使用情况: \n$explain\033[0m"
    
    network_ifs=`ifconfig |grep "<UP,BROADCAST,RUNNING,MULTICAST>" |awk -F ':' '{print $1}'`
    network_flow=`sar -n DEV |grep -v Average |grep $network_ifs |tail`
    echo -e "\033[36m$network_flow\033[0m"
}

#脚本运行入口
run(){
        while true;do
        menu

        case $num in
        "1")
                #1、查看系统负载
                    load_average
                    ;;
        "2")
                #2、查看CPU消耗%
                    cpu_use_percent
                    ;;
        "3")
                #3、查看内存消耗%
                    mem_use_percent
                    ;;
        "4")    #4、查看SWAP消耗%
                    swap_use_percent
                    ;;
        "5")    #5、查看磁盘消耗%
                    disk_use_percent
                    ;;
        "6")    #6、查看inode消耗%
                    inode_use_percent
                    ;;
        "7")    #7、查看磁盘IO
                    disk_io
                    ;;
        "8")    #8、查看网络流量
                    network_flow
                    ;;
        "9")    #9、一键查看所有情况
                    load_average
                    cpu_use_percent
                    mem_use_percent
                    swap_use_percent
                    disk_use_percent
                    inode_use_percent
                    disk_io
                    network_flow
                    exit 0
                    ;;
        "10")   #10、退出脚本
                    exit 0
                    ;;
          *)
                    ;;
        esac
        done
}

#调用脚本运行入口
run

管理docker

具体要求如下:

1)脚本支持启动全部容器、关闭全部容器、删除全部容器;

2)需要提示用户如何使用该脚本,需给出范例。

#!/bin/bash
#用于管理docker容器

while ture
do
    read -p "请输入你要执行的操作:(stop/start/rm)" opt
    
    if [ -z "$opt" ]
    then
        echo "请输入你的操作"
        continue
    else
        break
    fi
done

docker ps -a |awk '{print $1}' > /tmp/id.txt

case $opt in
  stop)
    for id in `cat /tmp/id.txt`
    do
        docker stop $id
    done
    ;;
  start)
    for id in `cat /tmp/id.txt`
    do
        docker start $id
    done
    ;;
  rm)
    for id in `cat /tmp/id.txt`
    do
        read -p "将要删除容器$id,是否继续?(y|n)" c
        case $c in
          y|Y)
            docker rm -f $id
            ;;
          n|N)
            echo "容器$id不会被删除"
            ;;
          *)
            echo "你只能输入 y/Y或者n/N"
            ;;
        esac
    done
  *)
    echo "你只能输入 start/stop/rm"
    ;;
  esac

Shell多线程备份数据库

本案例就是实现shell多线程备份数据库,具体要求如下:

1)公司的业务量比较大,有100个数据库需要全量备份,而每个数据库的数据量高达几十GB
(注意:每一个库都为一个独立的实例,即有着独立的ip:port);

2)预估每一个库的备份时间为30分钟左右,要求在5个小时内完成;

3)假设100个库的库名、host、port以及配置文件路径都存到一个文件里,文件名字为 /tmp/databases.list ;

4)格式为:db1 10.10.10.2 3308 /data/mysql/db1/my.cnf 。

#!/bin/bash
#多线程备份数据库
#备份数据库使用xtrabackup(由于涉及到myisam,命令为innobackupex)

exec &> /tmp/mysql_bak.log

if ! which inoobackupex &>/dev/null
then
    echo "安装xtrabackup工具"
    yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
    yum install percona-xtrabackup-24
    
    if [ $? -ne 0 ]
    then
        echo -e "\033[31m安装xtrabackup工具出错,请检查\033[0m"
        exit 1
    fi
fi

bakdir=/data/backup/mysql
bakuser=vyNctM
bakpass=99omeaBHh

bak_data()
{
    db_name=$1
    db_host=$2
    db_port=$3
    cnf=$4
    
    [ -d $bakdir/$db_name ] || mkdir -p $bakdir/$db_name
    innobackupex --defaults-file=$4 --host=$2 --port=$3 --user=$bakuser --password=$bakpass --databases=$1 $bakdir
    
    if [ $? -ne 0 ]
    then
        echo -e "\033[31m备份数据库$1出现问题\033[0m"
    fi
}

fifofile=/tmp/$$
mkfifo $fifofile
exec 1000<>$fifofile

n=10
for ((i=0;i<$n;i++))
do
    echo >&1000         # 0-9,创建10个线程
done

cat /tmp/databases.list |while read line
do
    read -u1000
    {
        bak_data `echo $line`
        echo >&1000
    } &
done

wait
exec 1000>&-        #删除fd1000
rm -f $fifofile     #删除命名管道

脚本中,

1、exec &> /tmp/mysql_bak.log ,将正确输出和错误输出都重定向到 /tmp/mysql_bak.log
2、$$表示本进程PID,mkfifo命令创建命名管道
3、read line ,line为变量名,将接下来的输入赋值给line

监测 Nginx 访问日志 502 情况,并做相应动作

假设服务器环境为 lnmp,近期访问经常出现 502 现象,且 502 错误在重启 php-fpm 服务后消失,因此需要编写监控脚本,一旦出现 502,则自动重启 php-fpm 服务。

#场景:
#1.访问日志文件的路径:/data/log/access.log
#2.脚本死循环,每10秒检测一次,10秒的日志条数为300条,出现502的比例不低于10%30条)则需要重启php-fpm服务
#3.重启命令为:/etc/init.d/php-fpm restart
#!/bin/bash
###########################################################
#监测Nginx访问日志502情况,并做相应动作
###########################################################
log=/data/log/access.log
N=30 #设定阈值
while :do
#查看访问日志的最新300条,并统计502的次数
err=`tail -n 300 $log |grep -c '502" '` 
if [ $err -ge $N ] 
then
/etc/init.d/php-fpm restart 2> /dev/null 
#设定60s延迟防止脚本bug导致无限重启php-fpm服务
sleep 60
fi
sleep 10
done

检测两台服务器指定目录下的文件一致性

#!/bin/bash
######################################
检测两台服务器指定目录下的文件一致性
#####################################
#通过对比两台服务器上文件的md5值,达到检测一致性的目的
dir=/data/web
b_ip=192.168.88.10
#将指定目录下的文件全部遍历出来并作为md5sum命令的参数,进而得到所有文件的md5值,并写入到指定文件中
find $dir -type f|xargs md5sum > /tmp/md5_a.txt
ssh $b_ip "find $dir -type f|xargs md5sum > /tmp/md5_b.txt"
scp $b_ip:/tmp/md5_b.txt /tmp
#将文件名作为遍历对象进行一一比对
for f in `awk '{print 2} /tmp/md5_a.txt'`do
#以a机器为标准,当b机器不存在遍历对象中的文件时直接输出不存在的结果
if grep -qw "$f" /tmp/md5_b.txt
then
md5_a=`grep -w "$f" /tmp/md5_a.txt|awk '{print 1}'`
md5_b=`grep -w "$f" /tmp/md5_b.txt|awk '{print 1}'`
#当文件存在时,如果md5值不一致则输出文件改变的结果
if [ $md5_a != $md5_b ]then
echo "$f changed."
fi
else
echo "$f deleted."
fi
done

定时清空文件内容,定时记录文件大小

#!/bin/bash
#################################################################
每小时执行一次脚本(任务计划),当时间为0点或12点时,将目标目录下的所有文件内#容清空,但不删除文件,其他时间则只统计各个文件的大小,一个文件一行,输出到以时#间和日期命名的文件中,需要考虑目标目录下二级、三级等子目录的文件
################################################################
logfile=/tmp/`date +%H-%F`.log
n=`date +%H`
if [ $n -eq 00 ] || [ $n -eq 12 ]
then
#通过for循环,以find命令作为遍历条件,将目标目录下的所有文件进行遍历并做相应操作
for i in `find /data/log/ -type f`
do
true > $i
done
else
for i in `find /data/log/ -type f`
do
du -sh $i >> $logfile
done
fi

计算文档每行出现的数字个数,并计算整个文档的数字总数

#!/bin/bash
#########################################################
#计算文档每行出现的数字个数,并计算整个文档的数字总数
########################################################
#使用awk只输出文档行数(截取第一段)
n=`wc -l a.txt|awk '{print $1}'`
sum=0
#文档中每一行可能存在空格,因此不能直接用文档内容进行遍历
for i in `seq 1 $n`do
#输出的行用变量表示时,需要用双引号
line=`sed -n "$i"p a.txt`#wc -L选项,统计最长行的长度
n_n=`echo $line|sed s'/[^0-9]//'g|wc -L`
echo $n_nsum=$[$sum+$n_n]
done
echo "sum:$sum"

杀死所有脚本

#!/bin/bash
################################################################
#有一些脚本加入到了cron之中,存在脚本尚未运行完毕又有新任务需要执行的情况,
#导致系统负载升高,因此可通过编写脚本,筛选出影响负载的进程一次性全部杀死。
################################################################
ps aux|grep 指定进程名|grep -v grep|awk '{print $2}'|xargs kill -9

从 FTP 服务器下载文件

#!/bin/bash
if [ $# -ne 1 ]; then
echo "Usage: $0 filename"
fi
dir=$(dirname $1)
file=$(basename $1)
ftp -n -v << EOF   # -n 自动登录
open 192.168.1.10  # ftp服务器
user admin password
binary   # 设置ftp传输模式为二进制,避免MD5值不同或.tar.gz压缩包格式错误
cd $dir
get "$file"
EOF

扫描主机端口状态

#!/bin/bash
HOST=$1
PORT="22 25 80 8080"
for PORT in $PORT; do
if echo &>/dev/null > /dev/tcp/$HOST/$PORT; then
echo "$PORT open"
else
echo "$PORT close"
fi
done

用 shell 打印示例语句中字母数小于6的单词

#示例语句:
#Bash also interprets a number of multi-character options.
#!/bin/bash
##############################################################
#shell打印示例语句中字母数小于6的单词
##############################################################
for s in Bash also interprets a number of multi-character options.
do
n=`echo $s|wc -c` 
if [ $n -lt 6 ] 
then
echo $s
fi
done

监控 httpd 的进程数,根据监控情况做相应处理

#!/bin/bash
###############################################################################################################################
#需求:
#1.每隔10s监控httpd的进程数,若进程数大于等于500,则自动重启Apache服务,并检测服务是否重启成功
#2.若未成功则需要再次启动,若重启5次依旧没有成功,则向管理员发送告警邮件,并退出检测
#3.如果启动成功,则等待1分钟后再次检测httpd进程数,若进程数正常,则恢复正常检测(10s一次),否则放弃重启并向管理员发送告警邮件,并退出检测
###############################################################################################################################
#计数器函数
check_service()
{
j=0
for i in `seq 1 5` 
do
#重启Apache的命令
 /usr/local/apache2/bin/apachectl restart 2> /var/log/httpderr.log    
#判断服务是否重启成功
if [ $? -eq 0 ] then
 break
else
j=$[$j+1] fi
#判断服务是否已尝试重启5if [ $j -eq 5 ] then
 mail.py exit
fi
done }while :do
n=`pgrep -l httpd|wc -l` 
#判断httpd服务进程数是否超过500
if [ $n -gt 500 ] then
 /usr/local/apache2/bin/apachectl restart 
if [ $? -ne 0 ] 
then
 check_service 
else
sleep 60
n2=`pgrep -l httpd|wc -l` 
#判断重启后是否依旧超过500
if [ $n2 -gt 500 ] 
then 
 mail.py exit
fi
fi
fi
#每隔10s检测一次
sleep 10done

iptables 自动屏蔽访问网站频繁的IP

场景:恶意访问,安全防范

1)屏蔽每分钟访问超过200的IP

方法1:根据访问日志(Nginx为例)

#!/bin/bash
DATE=$(date +%d/%b/%Y:%H:%M)
ABNORMAL_IP=$(tail -n5000 access.log |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}')
#先tail防止文件过大,读取慢,数字可调整每分钟最大的访问量。awk不能直接过滤日志,因为包含特殊字符。
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -I INPUT -s $IP -j DROP    fidone

方法2:通过TCP建立的连接

#!/bin/bash
ABNORMAL_IP=$(netstat -an |awk '$4~/:80$/ && $6~/ESTABLISHED/{gsub(/:[0-9]+/,"",$5);{a[$5]++}}END{for(i in a)if(a[i]>100)print i}')
#gsub是将第五列(客户端IP)的冒号和端口去掉
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -I INPUT -s $IP -j DROP    
fi
done

2)屏蔽每分钟SSH尝试登录超过10次的IP

方法1:通过lastb获取登录状态:

#!/bin/bash
DATE=$(date +"%a %b %e %H:%M") #星期月天时分  %e单数字时显示7,而%d显示07
ABNORMAL_IP=$(lastb |grep "$DATE" |awk '{a[$3]++}END{for(i in a)if(a[i]>10)print i}')for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -I INPUT -s $IP -j DROP    fidone

方法2:通过日志获取登录状态

#!/bin/bash
DATE=$(date +"%b %d %H")
ABNORMAL_IP="$(tail -n10000 /var/log/auth.log |grep "$DATE" |awk '/Failed/{a[$(NF-3)]++}END{for(i in a)if(a[i]>5)print i}')"
for IP in $ABNORMAL_IP; do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
        iptables -A INPUT -s $IP -j DROP        
echo "$(date +"%F %T") - iptables -A INPUT -s $IP -j DROP" >>~/ssh-login-limit.log    
fi
done

根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁

#!/bin/bash
####################################################################################
#根据web访问日志,封禁请求量异常的IP,如IP在半小时后恢复正常,则解除封禁
####################################################################################
logfile=/data/log/access.log
#显示一分钟前的小时和分钟
d1=`date -d "-1 minute" +%H%M`
d2=`date +%M`
ipt=/sbin/iptables
ips=/tmp/ips.txt
block()
{ 
#将一分钟前的日志全部过滤出来并提取IP以及统计访问次数
grep '$d1:' $logfile|awk '{print $1}'|sort -n|uniq -c|sort -n > $ips
#利用for循环将次数超过100的IP依次遍历出来并予以封禁
for i in `awk '$1>100 {print $2}' $ips` 
do
$ipt -I INPUT -p tcp --dport 80 -s $i -j REJECT 
echo "`date +%F-%T` $i" >> /tmp/badip.log 
done
}
unblock()
{ 
#将封禁后所产生的pkts数量小于10的IP依次遍历予以解封
for a in `$ipt -nvL INPUT --line-numbers |grep '0.0.0.0/0'|awk '$2<10 {print $1}'|sort -nr` 
do 
$ipt -D INPUT $a
done
$ipt -Z
}
#当时间在00分以及30分时执行解封函数
if [ $d2 -eq "00" ] || [ $d2 -eq "30" ] 
then
#要先解再封,因为刚刚封禁时产生的pkts数量很少
 unblock
 block 
else
 block
fi

判断用户输入的是否为IP地址

方法1:

#!/bin/bash
function check_ip(){
IP=$1
VALID_CHECK=$(echo $IP|awk -F. '$1< =255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')
if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$">/dev/null; then
if [ $VALID_CHECK == "yes" ]; then
echo "$IP available."
else
echo "$IP not available!"
fi
else
echo "Format error!"
fi
}
check_ip 192.168.1.1
check_ip 256.1.1.1

方法2:

#!/bin/bash
function check_ip(){
IP=$1
if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
FIELD1=$(echo $IP|cut -d. -f1)
FIELD2=$(echo $IP|cut -d. -f2)
FIELD3=$(echo $IP|cut -d. -f3)
FIELD4=$(echo $IP|cut -d. -f4)
if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then
echo "$IP available."
else
echo "$IP not available!"
fi
else
echo "Format error!"
fi
}
check_ip 192.168.1.1
check_ip 256.1.1.1

增加版:
加个死循环,如果IP可用就退出,不可用提示继续输入,并使用awk判断。

#!/bin/bash
function check_ip(){
    local IP=$1
VALID_CHECK=$(echo $IP|awk -F. '$1< =255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')
if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
if [ $VALID_CHECK == "yes" ]; then
            return 0
else
echo "$IP not available!"
            return 1
fi
else
echo "Format error! Please input again."
        return 1
fi
}
while true; do
    read -p "Please enter IP: " IP
    check_ip $IP
    [ $? -eq 0 ] && break || continue
done

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/577725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SAP QM 检验批上的‘容器数’

近期遇到一个问题。项目上质量部门发现某个原料批次收货打印出来的样品标签数不对。经查发现收货后触发的检验批上的‘容器数’&#xff08;No.Containers&#xff09;为999&#xff0c;实际上此次收货的箱数有1500多。 对于栏位‘容器数’&#xff0c;SAP的官方帮助文档&#…

指针 --- C语言

目录 1.指针是什么 2.指针和指针类型 3.野指针 4.指针运算 5.指针和数组 6.二级指针 7.指针数组 1.指针是什么 为了更好地管理内存&#xff0c;把内存分为了1个个小小的内存单元&#xff0c;大小是一个字节&#xff0c;每个字节给一个编号&#xff0c;内存的编号就是地…

《Spring Guides系列学习》guide56 - guide60

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gu…

Entity Framework Core 简明教程(3)- 关系处理

在数据库层面&#xff0c;表之间关系&#xff0c;通过主键、外键来实现&#xff0c;基于约束 (constraint) 和数据完整性来制约。 在 EF Core 技术层面&#xff0c;并不是简单地与数据库这些关系和约束对应&#xff0c;EF Core 有它自己的机制。本篇介绍 EF core 在处理表关系方…

HTML+CSS实训——Day03——仿网易云音乐的发现页界面

仓库链接:https://github.com/MengFanjun020906/HTML_SX 一些今天需要用到的知识点 弹性盒子 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedg…

二次元的登录界面

今天还是继续坚持写博客&#xff0c;然后今天给大家带来比较具有二次元风格的登录界面&#xff0c;也只是用html和css来写的&#xff0c;大家可以来看看&#xff01; 个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大一在校生&#xff0c;web前端开发专业 &…

[acwing周赛复盘] 第 105 场周赛20230527

[acwing周赛复盘] 第 105 场周赛20230527 总结5029. 极值数量1. 题目描述2. 思路分析3. 代码实现 5030. 核心元素1. 题目描述2. 思路分析3. 代码实现 5031. 矩阵扩张1. 题目描述2. 思路分析3. 代码实现 六、参考链接 总结 又是笨比的一周&#xff0c;只做出1题。T1 模拟T2 计…

leetcode刷题之链表相关问题(js)

21.合并两个有序链表 var mergeTwoLists function(list1, list2) {if(list1null) return list2if(list2null) return list1let newHead new ListNode(0,null) //创建一个虚拟节点let cur newHeadlet cur1 list1,cur2 list2while(cur1&&cur2){if(cur1.val<cur2.…

PowerToys Windows 工具集

Microsoft PowerToys | Microsoft Learn Microsoft PowerToys&#xff1a;用于自定义 Windows 的实用工具 项目2023/04/1918 个参与者 反馈 Microsoft PowerToys 是一组实用工具&#xff0c;可帮助高级用户调整和简化其 Windows 体验&#xff0c;从而提高工作效率。 安装 …

Unity之效应器

主要作用&#xff1a;在一个区域内让游戏对象受到力和扭矩力的作用 1、创建一个精灵&#xff08;绿色区域&#xff09; 2、为其添加碰撞器&#xff08;要将Used By Effector和is Trigger打钩&#xff09; 3、添加效应器组件 4、区域效应器参数 Use Collider Mask&#xff1a;…

第3章 Class and Object

构造函数 Guaranteed initialization with the constructor使用构造函数保证初始化 • If a class has a constructor, the compiler automatically calls that constructor at the point an object is created, before client programmers can get their hands on the o…

Solidity基础五

暂时的一事无成也代表将来万事皆有可能&#xff01; 目录 一、对Solidity文件的理解 二、Solidity的导sol文件&#xff08;库、合约&#xff09; 三、Solidity的继承 1.继承的分类 2.继承的可见性 3.父合约构造函数的传参 4.调用父合约成员 5.重写 四、Solidity的抽象…

Solidity基础八

别慌&#xff0c;月亮也在大海某处迷茫 目录 一、Solidity 编程风格 1. 代码布局 2. 代码中各部分的顺序 3. 命名约定 二、Solidity 智能合约编写过程 1. solidity Hello World 2. 版本声明 3. 导入声明 4. 合约声明 三、Solidity 合约结构 智能合约 Test 四、So…

Solidity基础六

生活本来就是平凡琐碎的&#xff0c;哪有那么多惊天动地的大事&#xff0c;快乐的秘诀就是不管对大事小事都要保持热情 目录 一、Solidity的特殊变量(全局) 二、Solidity的不可变量 immutable的赋值方式 三、Solidity的事件与日志 事件和日志加深理解 四、Solidity的异常…

EMLP2021 | Google大模型微调经典论文prompt tuning

一、概述 title&#xff1a;The Power of Scale for Parameter-Efficient Prompt Tuning 论文地址&#xff1a;https://arxiv.org/abs/2104.08691 代码&#xff1a;GitHub - google-research/prompt-tuning: Original Implementation of Prompt Tuning from Lester, et al, …

系列一、RuoYi前后端分离(登录密码加密)

一、部署前后端服务 http://doc.ruoyi.vip/ruoyi-vue/ 二、现象 若依前后端环境分离版本&#xff0c;本地部署好前后端环境后&#xff0c;访问登录接口密码是明文的&#xff0c;这样显然hi不安全的&#xff0c;如下图所示&#xff1a; 三、解决方法 3.1、加密流程 ①、后端…

Linux-0.11 文件系统namei.c详解

Linux-0.11 文件系统namei.c详解 模块简介 namei.c是整个linux-0.11版本的内核中最长的函数&#xff0c;总长度为700行。其核心是namei函数&#xff0c;即根据文件路径寻找对应的i节点。 除此以外&#xff0c;该模块还包含一些创建目录&#xff0c;删除目录&#xff0c;创建目…

Day2:Windows网络编程-TCP

今天开始进入Windows网络编程的学习&#xff0c;在学习的时候总是陷入Windows复杂的参数&#xff0c;纠结于这些。从老师的讲解中&#xff0c;这些内容属于是定式&#xff0c;主要学习写的逻辑。给自己提个醒&#xff0c;要把精力放在正确的位置&#xff0c;不要无端耗费精力。…

【JavaScript】文件分片上传

文章目录 普通文件上传分片上传整体流程技术点分析文件选择方式隐藏input框&#xff0c;自定义trigger拖拽上传 分片动态分片 计算哈希workerrequestIdleCallback抽样 请求并发控制进度展示手动中止/暂停 合并流式并发合并 反思分片命名问题并发控制代码实现的问题 参考文献 普…

ChatGPT桌面客户端支持gpt4模型,附使用说明

#软件核心功能&#xff1a; 1、支持OpenAI官方秘钥及API2D双秘钥使用&#xff1b;如果全局魔法&#xff0c;可以自己用官方秘钥&#xff1b;没魔法国内可直接使用API2D秘钥&#xff1b; 2、内置GPT4模型选项&#xff0c;如果你的官方秘钥支持可直接使用&#xff1b;你也可以注册…