Shell编程实战案例

2022-10-31 14:36:46 浏览数 (1)

shell编程实战案例

  • 监控一个机器存活状态
  • 监控一个端口存活
  • 找出使用cpu或者内存前十的进程
  • 监控内存使用率脚本
  • 监控硬盘io
  • 随机生成字符文件名
  • 多进程
代码语言:text复制
# 监控脚本注意事项

明确监控项
阀值是多少
监控方法(命令,思路(运行方法,调用方法))
返回值是什么

根据监控平台选择监控方式:例如zabbix,zabbix-agent,snmp,prometheus

监控主机及联网状态

1、监控目的

掌握在线业务机器及联网的 状态

2、监控方法

通过采用ICMP协议的ping命令对计算机进行ping测试,通过表示主机为开启并联网,不通则代表主机宕机或断网

3、监控思路

通过分析多次ping结果判断主机状态

4、实现实现

代码语言:shell复制
#!/usr/bin/env bash
#Description: 监控目标主机状态
#Author: mikelLam
#Created Time: 2021/12/27 17:43

# Constants
RESET='33[0m'
RED='33[38;5;1m'
GREEN='33[38;5;2m'
YELLOW='33[38;5;3m'
MAGENTA='33[38;5;5m'
CYAN='33[38;5;6m'

# Function

########################
# Print to STDERR
# Arguments:
#   $1  - string
# Returns:
#   None
#########################

main() {
    local IP=${1:?missing hostIP}
    for ((i=1;i<4;i  ));do
        if ping -c1 $IP &>/dev/null;then
            export ping_count"$i" = 1
        else 
            export ping_count"$i" = 0
        fi
    done

    sleep 0.3

    if [[ "$ping_count1" -eq "$ping_count2" ]] && [[ "$ping_count2" -eq "$ping_count3" ]] && [[ "$ping_count1" -eq 0 ]];then
        echo -e "${CYAN}$1 is down${RESET}"
    else
        echo -e "${GREEN}$1 is up${RESET}"
    fi

    unset ping_count1
    unset ping_count2
    unset ping_count3
}

main "$@"

监控主机服务状态

1、监控目的

掌握线上机器服务状态,保证服务正常运行

2、监控方法

采用telnet访问端口,通过返回数据分析判定结果

3、监控实现

代码语言:shell复制
#!/usr/bin/env bash
#Description: 监控一个服务端口
#Author: mikelLam
#Created Time: 2021/12/28 09:51

# Constants
RESET='33[0m'
RED='33[38;5;1m'
GREEN='33[38;5;2m'
YELLOW='33[38;5;3m'
MAGENTA='33[38;5;5m'
CYAN='33[38;5;6m'

# Function

########################
# Print to STDERR
# Arguments:
#   $1 - string
#   $2 - int
# Returns:
#   None
#########################

main() {
    local IP=${1:?missing hostIP}
    local PORT=${2:?missing port}
    [[ ! -x /usr/bin/telnet ]] && echo -e "${YELLOW} [WARNING] telnet: not found command${RESET}" && exit 1
    local TEMFILE=`mktemp port_status.XXX`
    echo -e "quit" |telnet $IP $PORT  &> $TEMFILE
    if egrep "^]" $TEMFILE &> /dev/null;then
        echo -e "${GREEN} [INFO] $IP $PORT is opening!${RESET}"
    else
        echo -e "${RED} [ERROR] $IP $PORT is closening!${RESET}"
    fi
    rm -rf $TEMFILE
}

main "$@"

监控使用cpu或内存前十的进程

1、监控目的

掌握系统进程对系统资源的使用情况,掌握机器的动态

2、监控方法

通过对任务管控器中的进程对内存或者CPU使用情况进行整合、排序得出结论

3、监控实现

代码语言:shell复制
#!/usr/bin/env bash
#Description: 统计使用内存和CPU前十进程
#Author: mikelLam
#Created Time: 2021/12/28 10:49

# Constants
RESET='33[0m'
RED='33[38;5;1m'
GREEN='33[38;5;2m'
YELLOW='33[38;5;3m'
MAGENTA='33[38;5;5m'
CYAN='33[38;5;6m'

# Function

########################
# Print to STDERR
# Arguments:
#   Missing to print
# Returns:
#   None
#########################

memory() {
    local MEMTEMFILE=`mktemp memory.XXX`
    top -b -n 1 > $MEMTEMFILE
    
    awk 'BEGIN {print "PIDtRESt%MEMtCOMMAND"}' 
    tail -n  8 $MEMTEMFILE | awk '
    {
        a[$1"#"$6"#"$10"#"$NF]  
    }
    END{
        for (i in a) {
            split(i,b,"#")
            print b[1]"t",b[2]"t",b[3]"t",b[4]
        }
    }' |sort -k 3 -n -r|head -n 10
    rm -rf $MEMTEMFILE
}

cpu() {
    local CPUTEMFILE=`mktemp cpu.XXX`
    top -b -n 1 > $CPUTEMFILE
    awk 'BEGIN {print "PIDt%CPUtCOMMAND"}' 
    tail -n  8 $CPUTEMFILE | awk '
    {   
        a[$1"#"$9"#"$NF]  
    }
    END{
        for (i in a) {
            split(i,b,"#")
            print b[1]"t",b[2]"t",b[3]
        }
    }' |sort -k 2 -n -r|head -n 10
    rm -rf $CPUTEMFILE
}

main() {
    echo -e "${YELLOW}==========================进程使用memory top10===================================${RESET}"
    memory
    echo -e "${YELLOW}==========================进程使用cpu top10======================================${RESET}" 
    cpu
}

main "$@"

监控内存使用率

1、监控目的

通过监控内存使用率判定机器内存资源消耗情况,及时处理并优化资源配比

2、监控方法

通过以下命令对内存总量、使用量进行截取,取得内存使用率,并根据阀值进行判断

3、监控命令

  • free
  • cat /proc/meminfo

4、监控指标

  • 内存使用率
  • buffer&cache

5、监控实现

代码语言:shell复制
#!/usr/bin/env bash
#Description: 内存使用率统计脚本
#Author: mikelLam
#Created Time: 2021/12/28 14:42

# Constants
RESET='33[0m'
RED='33[38;5;1m'
GREEN='33[38;5;2m'
YELLOW='33[38;5;3m'
MAGENTA='33[38;5;5m'
CYAN='33[38;5;6m'

# Function

########################
# Print to STDERR
# Arguments:
#   Missing to print
# Returns:
#   None
#########################

main() {
    memory_used=`head -2 /proc/meminfo |awk 'NR==1{t=$2}NR==2{f=$2;print(t-f)*100/t"%"}'`
    memory_cache=`head -5 /proc/meminfo |awk 'NR==1{t=$2}NR==5{c=$2;print c*100/t"%"}'`
    memory_buffer=`head -4 /proc/meminfo |awk 'NR==1{t=$2}NR==4{b=$2;print b*100/t"%"}'`
    echo -e "${CYAN} =========================内存使用率==========================${REST}"
    echo -e "${YELLOW}memory_used:${RESET} $memory_usedt"
    echo -e "${YELLOW}buffer:${RESET} $memory_buffert"
    echo -e "${YELLOW}cached:${RESET} $memory_cache"
}

main "$@"

监控IO使用情况

1、磁盘说明

磁盘在系统中负责存储和读取任务,磁盘的处理速度直接影响了计算机的速度,目前常用的磁盘有两种:固态和机械硬盘

固态磁盘: 没有IO瓶颈,读写快,存储颗粒有擦写限制,价格高,容量小 机械磁盘: 靠电机带动磁盘转动,通过磁头读取或存储数据,读写速度和磁盘转速有关,容量大、价格低,大量读写容易造成IO瓶颈

2、监控目的

随时掌握IO的使用情况,防止IO性能瓶颈

3、监控指标

  • IO列队长度
  • IOPS
  • 磁盘吞吐量

4、监控命令

iostat 用法: iostat [ 选项 ] [ <时间间隔> [ <次数> ] ] 常用选项说明: -c:只显示系统CPU统计信息,即单独输出avg-cpu结果,不包括device结果 -d:单独输出Device结果,不包括cpu结果 -k/-m:输出结果以kB/mB为单位,而不是以扇区数为单位 -x:输出更详细的io设备统计信息 interval/count:每次输出间隔时间,count表示输出次数,不带count表示循环输出

iostat,结果为从系统开机到当前执行时刻的统计信息

输出含义:

avg-cpu: 总体cpu使用情况统计信息,对于多核cpu,这里为所有cpu的平均值。重点关注iowait值,表示CPU用于等待io请求的完成时间。

%user:CPU处在用户模式下的时间百分比。

%nice:CPU处在带NICE值的用户模式下的时间百分比。

%system:CPU处在系统模式下的时间百分比。

%iowait:CPU等待输入输出完成时间的百分比。

%steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。

%idle:CPU空闲时间百分比。

Device: 各磁盘设备的IO统计信息。各列含义如下:

Device: 以sdX形式显示的设备名称

rrqm/s: 每秒对该设备的读请求被合并次数,文件系统会对读取同块(block)的请求进行合并

wrqm/s: 每秒对该设备的写请求被合并次数

r/s: 每秒完成的读次数

w/s: 每秒完成的写次数

rkB/s: 每秒读数据量(kB为单位)

wkB/s: 每秒写数据量(kB为单位)

avgrq-sz:平均每次IO操作的数据量(扇区数为单位)

avgqu-sz: 平均等待处理的IO请求队列长度

await: 平均每次IO请求等待时间(包括等待时间和处理时间,毫秒为单位)

svctm: 平均每次IO请求的处理时间(毫秒为单位)

%util: 采用周期内用于IO操作的时间比率,即IO队列非空的时间比率

代码语言:text复制
重点关注参数
1、iowait% 表示CPU等待IO时间占整个CPU周期的百分比,如果iowait值超过50%,或者明显大于%system、%user以及%idle,表示IO可能存在问题。
2、avgqu-sz 表示磁盘IO队列长度,即IO等待个数。
3、await 表示每次IO请求等待时间,包括等待时间和处理时间
4、svctm 表示每次IO请求处理的时间
5、%util 表示磁盘忙碌情况,一般该值超过80%表示该磁盘可能处于繁忙状态。
如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。如果 svctm 比较接近 await,
说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。如果avgqu-sz比较大,
也表示有大量io在等待。

5、监控实现

代码语言:shell复制
#!/usr/bin/env bash
#Description: 磁盘使用情况统计脚本
#Author: mikelLam
#Created Time: 2021/12/28 15:20

# Constants
RESET='33[0m'
RED='33[38;5;1m'
GREEN='33[38;5;2m'
YELLOW='33[38;5;3m'
MAGENTA='33[38;5;5m'
CYAN='33[38;5;6m'

# Function

########################
# Print to STDERR
# Arguments:
#   Missing to print
# Returns:
#   None
#########################

main() {
    device_num=`iostat -x|grep "^vd[a-z]"|wc -l`
    echo -e "${CYAN} =========================磁盘使用情况==========================${RESET}"
    awk 'BEGIN {print "devicetavgqu-sz"}'  
    iostat -x 1 3|egrep "^vd[a-z]"|tail -n  $((device_num 1))|awk '{io_long[$1] =$9}END{for (i in io_long) print i"t",io_long[i]}'
}

main "$@"

批量生成随机字符文件名

1、要求

生成10个txt文件, 每个文件名包含10个随机小写字母

2、分析

  • 采用openssl 生成40位随机数
  • 替换=掉非小写字母的字符
  • 利用cut截取10位

3、实现

代码语言:shell复制
#!/user/bin/env bash
#Description: 生成随机字符文件名
#Author: mikelLam
#Created Time: 2021/12/28 16:08

# Function

########################
# Print to STDERR
# Arguments:
#   Missing to print
# Returns:
#   None
#########################

main() {
    local PATH="/root/files"
    [[ -d "${PATH}" ]] || mkdir -pv $PATH
    for n in `seq 10`;do
        file_name=$(openssl rand -base64 40|sed 's#[^a-z]##g'|cut -c 2-10)
        touch $PATH/${file_name}.txt
    done
    tree $PATH
    rm -rf $PATH
}

main "$@"

多进程

1、分析

通过临时文件作为队列,来读写任务

2、实现

代码语言:shell复制
#!/usr/bin/env bash
#Description: 
#Author: mikelLam
#Created Time: 2021/12/28 16:08


# Function

########################
# Print to STDERR
# Arguments:
#   Missing to print
# Returns:
#   None
#########################

main() {
    THREAD_NUM=10
    if [[ -a tmp ]];then
        rm tmp
    fi

    mkfifo tmp
    exec 9<>tmp

    for (( i=0;i<$THREAD_NUM;i  ));do
        echo -en "n" 1>&9
    done

    fn_num() {
        a=$1
        b=$(( a % 10 ))
        echo "======>$a"
        sleep $b
        echo "<=====$a"
    }

    for (( i=0;i<100;i  ));do
        read -u 9
        {
            fn_num $i
            echo -en "n" 1>&9
        }&
    done

    wait
    echo "over"
    exec 9>&-
    exec 9<&-
    rm -rf tmp
}

main "$@"

防止暴力破解

1、分析

通过检测访问失败次数过多IP数,加入到黑名单中

2、实现

代码语言:shell复制
#!/usr/bin/env bash
#Description: 
#Author: mikelLam
#Created Time: 2022/05/06 10:58


# Function

########################
# Print to STDERR
# Arguments:
#   Missing to print
# Returns:
#   None
#########################

main() {
    [[ -f "/usr/local/bin/failed" ]] || touch /usr/local/bin/failed
    cat /var/log/secure|awk '/Failed/{print $(NF-3)}'|grep [0-9]|sort|uniq -c|sort -rn|awk '{print $2"="$1}' > /usr/local/bin/failed
    for i in `cat /usr/local/bin/failed`
    do
        IP=`echo $i |awk -F = '{print $1}'`
        NUM=`echo $i | awk -F = '{print $2}'`
        if [ $NUM -gt 5 ];then
            grep $IP /etc/hosts.deny > /dev/null
            if [ $? -eq 0 ];then
                echo "sshd:$IP:deny" >> /etc/hosts.deny
            fi
        fi
    done
}

main "$@"

0 人点赞