利用shell脚本写一个系统性能分析工具

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 项目实战1.系统性能分析1.利用select循环实现系统工具箱

项目实战1.系统性能分析

1.利用select循环实现系统工具箱

select格式和for格式一致,但是select 变量名 in xxx xxx都将打印成菜单

#!/bin/bash
PS3=“enter parment: ”
select xtgjx in disk_info filesystem_info ip_info mem_info cpu_info quit
do
        case $xtgjx in
        disk_info)
                lsblk
                ;;
        filesystem_info)
                df -HT
                ;;
        ip_info)
                ifconfig | awk '/inet/{if($2~/([0-9]{1,3}.){3}[0-9]{1,3}/){print $2}}'
                ;;
        mem_info)
                free -g
                ;;
        cpu_info)
                uptime
                ;;
        quit)
                break
                ;;
        *)
                echo "error parment"
        esac
done
执行:./select_xtgjx.sh
1) disk_info      3) ip_info    5) cpu_info
2) filesystem_info  4) mem_info   6) quit
#? 1
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   50G  0 disk 
├─sda1            8:1    0    1G  0 part /boot
└─sda2            8:2    0   49G  0 part 
  ├─centos-root 253:0    0   47G  0 lvm  /
  └─centos-swap 253:1    0    2G  0 lvm  [SWAP]
sdb               8:16   0  100G  0 disk 
└─sdb1            8:17   0  100G  0 part /my_scripts
sr0              11:0    1  4.3G  0 rom  /media
#? 
如果觉得#?不好看可以重新定义PS3的变量值进行更改,定义时变量值一定要加引号
 ./select_xtgjx.sh
1) disk_info      3) ip_info    5) cpu_info
2) filesystem_info  4) mem_info   6) quit
enter parment: 
如果希望每次执行完都弹出菜单,可以套一个while循环,在没执行完菜单对应的命令后执行一个break跳出当前循环,也就是跳出select循环,虽然跳出了select循环但是还有while循环因此可以实现每执行一部分就显示菜单内容
PS3="enter parment: "
while :
do
select xtgjx in disk_info filesystem_info ip_info mem_info cpu_info quit
do
        case $xtgjx in
        disk_info)
                lsblk
                break
                ;;
        filesystem_info)
                df -HT
                break
                ;;
        ip_info)
                ifconfig | awk '/inet/{if($2~/([0-9]{1,3}.){3}[0-9]{1,3}/){print $2}}'
                break
                ;;
        mem_info)
                free -g
                break
                ;;
        cpu_info)
                uptime
                break
                ;;
        quit)
                exit
                ;;
        *)
                echo "error parment"
        esac
done
done

2.命令技巧

其中使用了NR==3表示遇到第三行才会模式匹配
UTIL=`vmstat | awk '{if(NR==3){print 100-$15"%"}}'` 
这里用到了iostat命令,-d表示打印磁盘,-x表示列出详细信息
详细的iostat参数解释参照:https://www.jellythink.com/archives/438
WRITE=`iostat -d -x | awk '/^[s|v]/{OFS=":";print $1,$7"KB"}'` 
过滤出每块磁盘的大小
这里可以直接/Disk/不用加.*因为我们用到了&&还要匹配下一个规则,因为我们要打印第二列磁盘名字和第三列磁盘的大小,由于磁盘大小由小数点,因此我们使用printf 使用参数%d只显示整数,由于printf将值都显示在一行,因此最后我们使用print打印一个GB然后换行
精确匹配
fdisk -l | awk '/^Disk.*bytes/ && /\/dev/{printf $2" ";printf "%d",$3;print "GB"}'
差异匹配1
fdisk -l | awk '/^Disk/ && /\/dev/{printf $2;printf "%d",$3;print "GB"}'
差异匹配2
fdisk -l | awk '/^Disk.*bytes/{printf $2" ";printf "%d",$3;print "GB"}'
不使用printf实现
fdisk -l | awk '/^Disk.*bytes/{print $2,int($3)"GB"}'
如果变量内容由多行,引用是请用{}引起来例如
使用echo -e是为了支持反斜杠中的转义操作例如下面使用的\n表示换行
echo -e "disk total: \n${DISK_TOTAL}"
1.cpu利用率与负载实现方式:
定义i的值然后进行while循环,然后使用vmstat+awk过滤出util、user、sys、wait的分别对应的值如vmstat | awk '{if(NR==3){print $13"%"}}',然后在用echo列出这些变量值
2.磁盘io负载实现方式:
定义while循环,使用iostat+wak过滤出util、read、write、iowait的列如iostat -d -x | awk '/^[s|v]/{OFS=": ";print $1,$NF"%"}'然后用echo打印出来
3.磁盘使用率:
定义日志文件,然后使用fdisk -l awk过滤出磁盘名、大小,在用df命令过滤出磁盘的使用率,写一个for循环,如果使用率大于90就打印出90的那个磁盘名,最后echo 超过90的磁盘名和实际使用率并输出到日志we文件中,然后循环结束,打印出总量,在判断日志文件是否存在,如果存在就把日志内容输出,不存在则说没有磁盘使用率超过90%
4.求磁盘利用率、磁盘inode节点,一般实现思路为:首先定义日志文件存放路径,然后定义磁盘的空间大小、磁盘使用率(用printf "%d",$5的形式取出数值)/inode值,然后使用for循环遍历值列表,如果i的值大于90则打印出哪一列对应的磁盘名,最后echo出磁盘名加使用率追加到日志文件中,然后使用if语句判断是否存在该日志文件,如果有则cat这个文件,并删掉,如果没有就提示没有超过90%
5.内存使用率
使用free -m结合awk打印出total、used、free、cache的值free -m | awk '{if(NR==2){printf "%.1f",$2/1024;print "G"}}',然后用echo输出
两种形式显示内存的大小,因为由于是虚拟机因此内存只有512M,所以我们使用printf来打印出浮点数
保留1位小数点,然后用公式算一下最后打印个G
free -m | awk '{if(NR==2){printf "%.1f",$2/1024;print "G"}}'
free -m | awk '{if(NR==2){printf "%.1f",$2/1024}} END{print "G"}'
6.tcp状态
直接上命令,然后打印netstat -ant | awk '/^tcp/{state[$NF]++} END{for (i in state){print i,state[i]}}'
统计tcp状态
netstat -ant | awk '/^tcp/{state[$NF]++} END{for (i in state){print i,state[i]}}'
ss -ant  | awk '!/State/{state[$1]++} END{for(i in state){print i,state[i]}}'
7.打印占用CPU最多的前十个进程
第一种
使用ps命令结合awk命令判断第三列如果大于0.1(因为如果CPU不大于0.1,匹配没有意义)那么就使用printf(不会换行)打印“PID:”在打印出第二列的值,在打印一个”CPU:“并且打印出第三列的值,在打印一个---->,清晰,打印完后,我们用到了for循环,因为每一个进程都有不同的参数,所以我们无法确定他有多少列,因此我们使用for循环如果i小于NF也就是字段数,那么每次加1,在使用if判断是否等于NF如果等于那么就说明打印到了最后一个参数,然后我们就换行,否则的话就一直打印,知道打印到最后一列,然后进行换行,这样可以有效地把进程所有参数打印出来
ps aux | awk '{if($3>0.1){{printf "PID: "$2 " CPU: "$3 "%----->"}for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}'
第二种比较直观
ps axu | awk '{if($3>0.1){print "PID: "$2,"CPU: "$3,"------>",$NF}}' | sort -k4 | head -10
cputop10实现思路
首先定义CPU日志文件,然后设置i的值,并开始while循环,$i -le 3循环三次,在循环体中,使用ps命令结合awk命令,打印出pid、cpu、进程命令,使用sort命令排序别结合head只显示前10个,然后追加到日志文件中,在使用if判断,日志文件是否为空,不为空打印文件内容,为空就打印没有进程占用CPU,打印前10个进程占用的命令:ps aux | awk '{if($3>0.1){{printf "PID: "$2 " CPU:" $3 "%--->"}for (i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}',if后面使用双{}是为了将f or也连接在一起,当第一个if成立后面的for才会执行,如果是一个{}那么不管条件成不成立都会全部打印一下最后一列
也可以直接这看
ps aux  | awk '{if($3>0.1){print $0}}' | head -10
8.memtop10实现思路和cputop10一样
9.网卡流量
1M=1024Kb/8bit=128KB
网卡流量中RX是接受,TX是发送,6和7的位置不同,6中RX、TX位于第8行,RX是第4列,TX是低9列,而7中RX位于第五行TX位于第7行都是第5列
也可以根据RX或者TX查找
RX=ifconfig ens33 | awk '/bytes/{if(NR==5){print $5} else if(NR==8){print $4}}'
TX=ifconfig ens33 | awk '/bytes/{if(NR==7){print $5} else if(NR==8){print $9}}'
网络流量实现方式
首先写一个死循环,使用read提示用户检查那块网卡的流量,用户输的网卡存在则跳出循环,在写一个循环,循环三次,其中先定义rx和tx的值,然后sleep 1秒在重新定义一个值,因为每秒都会发生改变,最后定义IN的变量(也就是RX)用一秒后的值减去1秒前的值除于1024在除于128,除于1024是为了得到Kb除于128是为了得出多少M最后打印出RX的值和TX的值

3.整个脚本实现方式

#!/bin/bash
#系统性能分析工具
#检测操作系统版本
YELLOW_COLOR='\e[033m'  #黄
RED_COLOR='\e[031m' #红
GREEN_COLOR='\e[032m' #绿  
BLUE_COLOR='\e[034m'  #蓝
BLACK_COLOR='\e[0m' #黑
PINK_COLOR='\e[035m'  #粉
os_check() {
  if [ -e /etc/redhat-release ];then
    LINUX1=$(cat /etc/redhat-release | cut -d' ' -f1)
  else
    LINUX2=$(cat /etc/issue | awk '{print $1}')
  fi
  if [ "$LINUX1" == "CentOS" -o "$LINUX1" == "RedHat" ];then
    P_M=yum
  elif [ "$LINUX2" == "Ubuntu" -o "$LINUX2" == "ubuntu" ];then
    P_M=apt-get
  else
    echo "error system"
    exit 1
  fi
}
#检测是否是root登录的系统
if [ $LOGNAME != root ];then
  echo -e "${RED_COLOR}请使用root用户操作${BLACK_COLOR}"
  exit 2
fi
#检测是否安装vmstat
if ! which vmstat &>/dev/null;then
  echo -e "${RED_COLOR}vmstat 命令没有安装,现在开始安装...${BLACK_COLOR}"
  os_check
  $P_M -y install vmstat
  if [ $? -eq 0 ];then
    echo "-------------------------------------------------------------"
  fi
fi
#检测是否安装iostat
which iostat &>/dev/null
if [ $? -ne 0 ];then
  echo -e "${RED_COLOR}iostat 命令没有安装,现在开始安装...${BLACK_COLOR}" 
  os_check
  $P_M -y install iostat
  if [ $? -eq 0 ];then
    echo "-------------------------------------------------------------"
  fi
fi
#使用select构造菜单并添加每个菜单需要执行的命令
while :
do
  select menu in cpu_load disk_load disk_use disk_inode mem_use tcp_status cpu_top10 mem_top10 traffic clearscreen quit 
  do
    case $menu in
    cpu_load)
      #CPU利用率与负载
      echo "------------------------------------"
      i=1
      while [[ $i -le 3 ]]
      do
        echo -e "${GREEN_COLOR}参数值$i ${BLACK_COLOR}"
        UTIL=`vmstat | awk '{if(NR==3){print 100-$15"%"}}'` #第15列是id对应的列,表示空闲的,用100减去空闲的就是已经使用的
        USER=`vmstat | awk '{if(NR==3){print $13"%"}}'`   #第13列是us对应的列,这里表示已使用的CPU中用户占用了多少
        SYS=`vmstat |awk '{if(NR==3){print $14"%"}}'`     #第14列是sy对应的列,这里表示已使用的CPU中系统占了多少
        IOWAIT=`vmstat | awk '{if(NR==3){print $(NF -1)"%"}}'`  #倒数第二列也就是16列,这里表示IOwait在cpu中占用了多少
        echo "cpu used: $UTIL"
        echo "user used: $USER"
        echo "system used: $SYS"
        echo "io wait used: $IOWAIT"
        let i++
        sleep 1
      done  
      echo "------------------------------------"
      break
      ;;
    disk_load)
      #磁盘I/O负载
      echo "------------------------------------"
      i=1
      while [[ $i -le 3 ]]
      do
        echo -e "${GREEN_COLOR}参数值$i ${BLACK_COLOR}"
        UTIL=`iostat -d -x | awk '/^[s|v]/{OFS=": ";print $1,$NF"%"}'`  #util是IO消耗的CPU占比,-d,-x参数分别表示只列出磁盘和详细信息
        READ=`iostat -d -x | awk '/^[s|v]/{OFS=": ";print $1,$6"KB"}'`  #打印出每秒向磁盘读多少字节数
        WRITE=`iostat -d -x | awk '/^[s|v]/{OFS=":";print $1,$7"KB"}'`  #打印出每秒向磁盘写多少字节数
        IOWAIT=`vmstat | awk '{if(NR==3){print $(NF-1)"%"}}'`
        echo -e "UTIL:"   
        echo -e "${UTIL}"
        echo -e "io wait used: $IOWAIT"
        echo -e "Read/s: \n$READ"
        echo -e "Write/s: \n$WRITE" 
        i=$(($i+1))
        sleep 1
      done
      echo "------------------------------------"
      break
      ;;
    disk_use)
      #磁盘使用率
      DISK_LOG=/tmp/disk_user.log   #磁盘使用日志存放路径
      DISK_TOTAL=`fdisk -l | awk '/^Disk.*bytes/{print $2,int($3)"GB"}'`  #打印出磁盘对应的大小
      DISK_USED=`df -h | awk '/^\/dev/{print int($(NF-1))}'`    #打印出磁盘的使用率
      for i in $DISK_USED     #遍历一下,因为不止一块磁盘
      do
        if [ $i -ge 90 ];then
          DISK_NAME=`df -h | awk '{if(int($5)=='''$i'''){print $6}}'`   #如果第五列磁盘使用率等于循环中i的值那么就打印第六列
          echo "${DISK_NAME} used is ${i}%..." >> $DISK_LOG   #将磁盘的名字和使用率对应起来追加到日志中
        fi
      done
      echo -e "disk total: \n${DISK_TOTAL}"
      if [ -e $DISK_LOG ];then
        echo "------------------------------------"
        df -h | awk '/^\/dev/{print $1":",$5}'      #如果使用了df -hT则先是$7,$6
        echo
        cat $DISK_LOG
        echo "------------------------------------"
        rm -rf $DISK_LOG
      else
        echo "------------------------------------"
        df -h | awk '/^\/dev/{print $1":",$5}'      #如果使用了df -hT则先是$7,$6
        echo
        echo -e "${BLUE_COLOR}Disk used no more than 90%...${BLACK_COLOR}"    #当前磁盘使用率没有超过90%的
        echo "------------------------------------"
      fi
      break
      ;;
    disk_inode)
      #磁盘inodes
      DKINODE_LOG=/tmp/disk_inode.log 
      DISK_INODE=`df -i | akw '/^\/dev/{print int($5)}'`    #df -i表示打印inode节点值
      for i in $DISK_INODE
      do
        if [ $i -ge 90 ];then
          DISK_INODE_NAME=`df -i | awk '{if(int($5)=='''$i'''){print $1}}'`
          echo "$DISK_INODE_NAME inodes is ${i}%" >> $DKINODE_LOG
        fi
      done
      if [ -e $DKINODE_LOG ];then
        echo "------------------------------------"
        df -i | awk '/^\/dev/{print $1":"$5}' 
        echo
        cat $DKINODE_LOG
        echo "------------------------------------"
      else
        echo "------------------------------------"
        df -i | awk '/^\/dev/{print $1":"$5}' 
        echo
        echo -e "${BLUE_COLOR}Disk inodes no more than 90%...${BLACK_COLOR}"
        echo "------------------------------------"
      fi
      break
      ;;
    mem_use)
      MEM_TOTAL=`free -m | awk '{if(NR==2){printf "%.1f",$2/1024;print "G"}}'`  #%.1f表示取小数点1位
      MEM_USED=`free -m | awk '{if(NR==2){printf "%.1f",$3/1024}} END{print "G"}'`
      MEM_FREE=`free -m | awk '{if(NR==2){printf "%.1f",$4/1024;print "G"}}'`
      MEM_CACHE=`free -m | awk '{if(NR==2){printf "%.1f",$6/1024;print "G"}}'`
      echo "------------------------------------"
      echo -e "memory total is ${MEM_TOTAL}"
      echo -e "memory used is ${MEM_USED}"
      echo -e "memory free is ${MEM_FREE}"
      echo -e "memory cache is ${MEM_CACHE}"
      MEM_FREE_INT=`free -m | awk '{if(NR==2){printf "%d",$4/1024}}'`
      if [ $MEM_FREE_INT -le 0 ];then
        echo -en  "${YELLOW_COLOR}mree memory is very low, if we need to clear the cache [y|n]: ${BLACK_COLOR}" 
        read action
        case $action in 
        y|Y)
          sync
          echo 3 > /proc/sys/vm/drop_caches
          echo -e "${PINK_COLOR}clear mem  ok...${BLACK_COLOR}"
          ;;
        n|N)
          ;;
        esac
      fi
      echo "------------------------------------"
      break
      ;;
    tcp_status)
      #tcp连接状态
      TCP_CONNECT=`netstat -ant | awk '/^tcp/{state[$NF]++} END{for (i in state){print i,state[i]}}'`
      echo "------------------------------------"
      echo -e "${YELLOW_COLOR}tcp connection status: ${BLACK_COLOR} \n$TCP_CONNECT"
      echo "------------------------------------"
      break
      ;;
    cpu_top10)
      #查看占用cpu最高的前十个进程
      echo "------------------------------------"
      CPU_LOG=/tmp/cpu_top10.log
      i=1
      while [[ $i -le 3 ]]
      do
        ps aux | awk '{if($3>0.1){{printf "PID: "$2 " CPU: " $3 "%----->"} for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}' | sort -k4 -nr | head -10  >> $CPU_LOG   #循环吃那个11列开始,如果i的值等于最后一列则换行,否则就一直打印直到最后一行
        if [[ -n `cat $CPU_LOG` ]];then   #查看日志中是否有文件
          echo -e "${GREEN_COLOR}参数值$i ${BLACK_COLOR}"
          cat $CPU_LOG
          > $CPU_LOG
        else
          echo -e "${RED_COLOR}No process using the CPU${BLACK_COLOR}"    #没有进程使用CPU
          break
        fi
        let i++
        sleep 1
      done
      rm -rf $CPU_LOG
      echo "------------------------------------"
      break
      ;;
    mem_top10)
      #查看占用内存最高的前十个进程
      echo "------------------------------------"
      MEM_LOG=/tmp/mem_top10.log
      i=1
      while [[ $i -le 3 ]]
      do
        ps aux | awk '{if($4>0.1){{printf "PID: "$2 " MEM: " $4 "%----->"} for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}' | sort  -k4 -nr | head -10 > $MEM_LOG
        if [[ -n `cat $MEM_LOG` ]];then
          echo -e "${GREEN_COLOR}参数值$i ${BLACK_COLOR}"
          cat $MEM_LOG
          > $MEM_LOG
        else
          echo -e "${RED_COLOR}No process using the memory${BLACK_COLOR}"
        fi
        let i++
        sleep 1
      done
      rm -rf $MEM_LOG
      echo "------------------------------------"
      break
      ;;
    traffic)
      #检测网络流量
      while true ;do
        echo -en "${YELLOW_COLOR}请输入要检测的网卡名称:${BLACK_COLOR}" 
        read network_cord
        NET_CORD_EX=`ifconfig | grep -c "$network_cord"`
        #if [ `ifconfig | grep -c "$network_cord"` -eq 1 ];then
        if [ $NET_CORD_EX -eq 1 ];then
          break
        else
          echo -e "${RED_COLOR}没有 '${network_cord}' 这块网卡,请重新输入${BLACK_COLOR}"
        fi
      done
      echo "------------------------------------"
      echo -e "${BLUE_COLOR}IN------OUT${BLACK_COLOR}"
      i=1
      while [[ $i -le 3 ]]
      do
        #centos6/7中ifconfig显示的内容略有差异
        #centos6中rx与tx行号位于8 rx是接收也就是in
        #centos7中rx位于5,tx位于7  tx是发送也就是out
        RX_IN=`ifconfig $network_cord | awk '/bytes/{if(NR==5){print $5} else if(NR==8){print $4}}'`
        TX_OUT=`ifconfig $network_cord | awk '/bytes/{if(NR==7){print $5} else if(NR==8){print $9}}'`
        sleep 1
        RX_IN_NEW=`ifconfig $network_cord | awk '/bytes/{if(NR==5){print $5} else if(NR==8){print $4}}'`
        TX_OUT_NEW=`ifconfig $network_cord | awk '/bytes/{if(NR==7){print $5} else if(NR==8){print $9}}'`
        IN=`awk 'BEGIN{printf "%.1f",'$(($RX_IN_NEW-$RX_IN))'/1024/128}'`
        OUT=`awk 'BEGIN{printf "%.1f",'$(($TX_OUT_NEW-$TX_OUT))'/1024/128}'`
        echo -e "${PINK_COLOR}RX IN is ${IN}MB/s,TX OUT is ${OUT}MB/s${BLACK_COLOR}"
        let i++
        sleep 1
      done
      echo "------------------------------------"
      break
      ;;
    clearscreen)
      clear
      break
      ;;
     quit)
      exit 3
      ;;
    *)
      echo "enter number"
      ;;
    esac
  done
done

4.改造成函数

4.1函数文件内容

#!/bin/bash
#系统性能分析工具
#检测操作系统版本
os_check() {
  if [ -e /etc/redhat-release ];then
    LINUX1=$(cat /etc/redhat-release | cut -d' ' -f1)
  else
    LINUX2=$(cat /etc/issue | awk '{print $1}')
  fi
  if [ "$LINUX1" == "CentOS" -o "$LINUX1" == "RedHat" ];then
    P_M=yum
  elif [ "$LINUX2" == "Ubuntu" -o "$LINUX2" == "ubuntu" ];then
    P_M=apt-get
  else
    echo "error system"
    exit 1
  fi
}
cpu_load_fy() {
  #CPU负载
  echo "------------------------------------"
  i=1
  while [[ $i -le 3 ]]
  do
    echo -e "${GREEN_COLOR}参数值$i ${BLACK_COLOR}"
    UTIL=`vmstat | awk '{if(NR==3){print 100-$15"%"}}'` #第15列是id对应的列,表示空闲的,用100减去空闲的就是已经使用的
    USER=`vmstat | awk '{if(NR==3){print $13"%"}}'`   #第13列是us对应的列,这里表示已使用的CPU中用户占用了多少
    SYS=`vmstat |awk '{if(NR==3){print $14"%"}}'`     #第14列是sy对应的列,这里表示已使用的CPU中系统占了多少
    IOWAIT=`vmstat | awk '{if(NR==3){print $(NF -1)"%"}}'`  #倒数第二列也就是16列,这里表示IOwait在cpu中占用了多少
    echo "cpu used: $UTIL"
    echo "user used: $USER"
    echo "system used: $SYS"
    echo "io wait used: $IOWAIT"
    let i++
    sleep 1
  done  
  echo "------------------------------------"
break
}
disk_load_fy() {
  #磁盘I/O负载
  echo "------------------------------------"
  i=1
  while [[ $i -le 3 ]]
  do
    echo -e "${GREEN_COLOR}参数值$i ${BLACK_COLOR}"
    UTIL=`iostat -d -x | awk '/^[s|v]/{OFS=": ";print $1,$NF"%"}'`  #util是IO消耗的CPU占比,-d,-x参数分别表示只列出磁盘和详细信息
    READ=`iostat -d -x | awk '/^[s|v]/{OFS=": ";print $1,$6"KB"}'`  #打印出每秒向磁盘读多少字节数
    WRITE=`iostat -d -x | awk '/^[s|v]/{OFS=":";print $1,$7"KB"}'`  #打印出每秒向磁盘写多少字节数
    IOWAIT=`vmstat | awk '{if(NR==3){print $(NF-1)"%"}}'`
    echo -e "UTIL:"   
    echo -e "${UTIL}"
    echo -e "io wait used: $IOWAIT"
    echo -e "Read/s: \n$READ"
    echo -e "Write/s: \n$WRITE" 
    i=$(($i+1))
    sleep 1
  done
  echo "------------------------------------"
  break
}
disk_use_fy() {
  #磁盘使用率
  DISK_LOG=/tmp/disk_user.log   #磁盘使用日志存放路径
  DISK_TOTAL=`fdisk -l | awk '/^Disk.*bytes/{print $2,int($3)"GB"}'`  #打印出磁盘对应的大小
  DISK_USED=`df -h | awk '/^\/dev/{print int($(NF-1))}'`    #打印出磁盘的使用率
  for i in $DISK_USED     #遍历一下,因为不止一块磁盘
  do
    if [ $i -ge 90 ];then
      DISK_NAME=`df -h | awk '{if(int($5)=='''$i'''){print $6}}'`   #如果第五列磁盘使用率等于循环中i的值那么就打印第六列
      echo "${DISK_NAME} used is ${i}%..." >> $DISK_LOG   #将磁盘的名字和使用率对应起来追加到日志中
    fi
  done
  echo -e "disk total: \n${DISK_TOTAL}"
  if [ -e $DISK_LOG ];then
    echo "------------------------------------"
    df -h | awk '/^\/dev/{print $1":",$5}'      #如果使用了df -hT则先是$7,$6
    echo
    cat $DISK_LOG
    echo "------------------------------------"
    rm -rf $DISK_LOG
  else
    echo "------------------------------------"
    df -h | awk '/^\/dev/{print $1":",$5}'      #如果使用了df -hT则先是$7,$6
    echo
    echo -e "${BLUE_COLOR}Disk used no more than 90%...${BLACK_COLOR}"    #当前磁盘使用率没有超过90%的
    echo "------------------------------------"
  fi
  break
}
disk_inode_fy() {
  #磁盘inodes
  DKINODE_LOG=/tmp/disk_inode.log 
  DISK_INODE=`df -i | akw '/^\/dev/{print int($5)}'`    #df -i表示打印inode节点值
  for i in $DISK_INODE
  do
    if [ $i -ge 90 ];then
      DISK_INODE_NAME=`df -i | awk '{if(int($5)=='''$i'''){print $1}}'`
      echo "$DISK_INODE_NAME inodes is ${i}%" >> $DKINODE_LOG
    fi
  done
  if [ -e $DKINODE_LOG ];then
    echo "------------------------------------"
    df -i | awk '/^\/dev/{print $1":"$5}' 
    echo
    cat $DKINODE_LOG
    echo "------------------------------------"
  else
    echo "------------------------------------"
    df -i | awk '/^\/dev/{print $1":"$5}' 
    echo
    echo -e "${BLUE_COLOR}Disk inodes no more than 90%...${BLACK_COLOR}"
    echo "------------------------------------"
  fi
  break
}
mem_use_fy() {
  MEM_TOTAL=`free -m | awk '{if(NR==2){printf "%.1f",$2/1024;print "G"}}'`  #%.1f表示取小数点1位
  MEM_USED=`free -m | awk '{if(NR==2){printf "%.1f",$3/1024}} END{print "G"}'`
  MEM_FREE=`free -m | awk '{if(NR==2){printf "%.1f",$4/1024;print "G"}}'`
  MEM_CACHE=`free -m | awk '{if(NR==2){printf "%.1f",$6/1024;print "G"}}'`
  echo "------------------------------------"
  echo -e "memory total is ${MEM_TOTAL}"
  echo -e "memory used is ${MEM_USED}"
  echo -e "memory free is ${MEM_FREE}"
  echo -e "memory cache is ${MEM_CACHE}"
  MEM_FREE_INT=`free -m | awk '{if(NR==2){printf "%d",$4/1024}}'`
  if [ $MEM_FREE_INT -le 0 ];then
    echo -en  "${YELLOW_COLOR}mree memory is very low, if we need to clear the cache [y|n]: ${BLACK_COLOR}" 
    read action
    case $action in 
    y|Y)
      sync
      echo 3 > /proc/sys/vm/drop_caches
      echo -e "${PINK_COLOR}clear mem  ok...${BLACK_COLOR}"
      ;;
    n|N)
      ;;
    esac
  fi
  echo "------------------------------------"
  break
} 
tcp_status_fy() {
  #tcp连接状态
  TCP_CONNECT=`netstat -ant | awk '/^tcp/{state[$NF]++} END{for (i in state){print i,state[i]}}'`
  echo "------------------------------------"
  echo -e "${YELLOW_COLOR}tcp connection status: ${BLACK_COLOR} \n$TCP_CONNECT"
  echo "------------------------------------"
  break
}
cpu_top10_fy() {
  #查看占用cpu最高的前十个进程
  echo "------------------------------------"
  CPU_LOG=/tmp/cpu_top10.log
  i=1
  while [[ $i -le 3 ]]
  do
    ps aux | awk '{if($3>0.1){{printf "PID: "$2 " CPU: " $3 "%----->"} for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}' | sort -k4 -nr | head -10  >> $CPU_LOG   #循环吃那个11列开始,如果i的值等于最后一列则换行,否则就一直打印直到最后一行
    if [[ -n `cat $CPU_LOG` ]];then   #查看日志中是否有文件
      echo -e "${GREEN_COLOR}参数值$i ${BLACK_COLOR}"
      cat $CPU_LOG
      > $CPU_LOG
    else
      echo -e "${RED_COLOR}No process using the CPU${BLACK_COLOR}"    #没有进程使用CPU
      break
    fi
    let i++
    sleep 1
  done
  rm -rf $CPU_LOG
  echo "------------------------------------"
  break
}
mem_top10_fy() {
  #查看占用内存最高的前十个进程
  echo "------------------------------------"
  MEM_LOG=/tmp/mem_top10.log
  i=1
  while [[ $i -le 3 ]]
  do
    ps aux | awk '{if($4>0.1){{printf "PID: "$2 " MEM: " $4 "%----->"} for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}' | sort  -k4 -nr | head -10 > $MEM_LOG
    if [[ -n `cat $MEM_LOG` ]];then
      echo -e "${GREEN_COLOR}参数值$i ${BLACK_COLOR}"
      cat $MEM_LOG
      > $MEM_LOG
    else
      echo -e "${RED_COLOR}No process using the memory${BLACK_COLOR}"
    fi
    let i++
    sleep 1
  done
  rm -rf $MEM_LOG
  echo "------------------------------------"
  break
}
traffic_fy() {
  #检测网络流量
  while true ;do
    echo -en "${YELLOW_COLOR}请输入要检测的网卡名称:${BLACK_COLOR}" 
    read network_cord
    NET_CORD_EX=`ifconfig | grep -c "$network_cord"`
    #if [ `ifconfig | grep -c "$network_cord"` -eq 1 ];then
    if [ $NET_CORD_EX -eq 1 ];then
      break
    else
      echo -e "${RED_COLOR}没有 '${network_cord}' 这块网卡,请重新输入${BLACK_COLOR}"
    fi
  done
  echo "------------------------------------"
  echo -e "${BLUE_COLOR}IN------OUT${BLACK_COLOR}"
  i=1
  while [[ $i -le 3 ]]
  do
    #centos6/7中ifconfig显示的内容略有差异
    #centos6中rx与tx行号位于8 rx是接收也就是in
    #centos7中rx位于5,tx位于7  tx是发送也就是out
    RX_IN=`ifconfig $network_cord | awk '/bytes/{if(NR==5){print $5} else if(NR==8){print $4}}'`
    TX_OUT=`ifconfig $network_cord | awk '/bytes/{if(NR==7){print $5} else if(NR==8){print $9}}'`
    sleep 1
    RX_IN_NEW=`ifconfig $network_cord | awk '/bytes/{if(NR==5){print $5} else if(NR==8){print $4}}'`
    TX_OUT_NEW=`ifconfig $network_cord | awk '/bytes/{if(NR==7){print $5} else if(NR==8){print $9}}'`
    IN=`awk 'BEGIN{printf "%.1f",'$(($RX_IN_NEW-$RX_IN))'/1024/128}'`
    OUT=`awk 'BEGIN{printf "%.1f",'$(($TX_OUT_NEW-$TX_OUT))'/1024/128}'`
    echo -e "${PINK_COLOR}RX IN is ${IN}MB/s,TX OUT is ${OUT}MB/s${BLACK_COLOR}"
    let i++
    sleep 1
  done
  echo "------------------------------------"
  break
}

4.2脚本内容

#!/bin/bash
#系统性能分析工具---函数实现
#检测操作系统版本
source /my_scripts/d12_xtxnfx/fun_system.fy
YELLOW_COLOR='\e[033m'  #黄
RED_COLOR='\e[031m'     #红
GREEN_COLOR='\e[032m'   #绿     
BLUE_COLOR='\e[034m'    #蓝
BLACK_COLOR='\e[0m'     #黑
PINK_COLOR='\e[035m'    #粉
#检测是否是root登录的系统
if [ $LOGNAME != root ];then
        echo -e "${RED_COLOR}请使用root用户操作${BLACK_COLOR}"
        exit 2
fi
#检测是否安装vmstat
if ! which vmstat &>/dev/null;then
        echo -e "${RED_COLOR}vmstat 命令没有安装,现在开始安装...${BLACK_COLOR}"
        os_check
        $P_M -y install vmstat
        if [ $? -eq 0 ];then
                echo "-------------------------------------------------------------"
        fi
fi
#检测是否安装iostat
which iostat &>/dev/null
if [ $? -ne 0 ];then
        echo -e "${RED_COLOR}iostat 命令没有安装,现在开始安装...${BLACK_COLOR}"        
        os_check
        $P_M -y install iostat
        if [ $? -eq 0 ];then
                echo "-------------------------------------------------------------"
        fi
fi
#使用select构造菜单并添加每个菜单需要执行的命令
while :
do
        select menu in cpu_load disk_load disk_use disk_inode mem_use tcp_status cpu_top10 mem_top10 traffic clearscreen quit
        do
                case $menu in
                cpu_load)
                        cpu_load_fy
                        ;;
                disk_load)
                        disk_load_fy
                        ;;
                disk_use)
                        disk_use_fy
                        ;;
                disk_inode)
                        disk_inode_fy
                        ;;
                mem_use)
                        mem_use_fy
                        ;;
                tcp_status)
                        tcp_status_fy
                        ;;
                cpu_top10)
                        cpu_top10_fy
                        ;;
                mem_top10)
                        mem_top10_fy
                        ;;
                traffic)
                        traffic_fy
                        ;;
                clearscreen)
                        clear
                        break
                        ;;
                 quit)
                        exit 3
                        ;;
                *)
                        echo "enter number"
                        ;;
                esac
        done
done

6.执行脚本显示所有内容

函数和5的是同一个文件

#!/bin/bash
#系统性能分析工具
#执行显示所有内容
#检测操作系统版本
source /my_scripts/d12_xtxnfx/fun_system.fy
YELLOW_COLOR='\e[033m'  #黄
RED_COLOR='\e[031m'     #红
GREEN_COLOR='\e[032m'   #绿     
BLUE_COLOR='\e[034m'    #蓝
BLACK_COLOR='\e[0m'     #黑
PINK_COLOR='\e[035m'    #粉
#检测是否是root登录的系统
if [ $LOGNAME != root ];then
        echo -e "${RED_COLOR}请使用root用户操作${BLACK_COLOR}"
        exit 2
fi
#检测是否安装vmstat
if ! which vmstat &>/dev/null;then
        echo -e "${RED_COLOR}vmstat 命令没有安装,现在开始安装...${BLACK_COLOR}"
        os_check
        $P_M -y install vmstat
        if [ $? -eq 0 ];then
                echo "-------------------------------------------------------------"
        fi
fi
#检测是否安装iostat
which iostat &>/dev/null
if [ $? -ne 0 ];then
        echo -e "${RED_COLOR}iostat 命令没有安装,现在开始安装...${BLACK_COLOR}"        
        os_check
        $P_M -y install iostat
        if [ $? -eq 0 ];then
                echo "-------------------------------------------------------------"
        fi
fi
#使用select构造菜单并添加每个菜单需要执行的命令
echo -e "${YELLOW_COLOR}cpu_load${BLACK_COLOR}"
cpu_load_fy
echo
echo
echo -e "${YELLOW_COLOR}disk_load${BLACK_COLOR}"
disk_load_fy
echo
echo
echo -e "${YELLOW_COLOR}disk_use${BLACK_COLOR}"
disk_use_fy
echo
echo
echo -e "${YELLOW_COLOR}disk_inode${BLACK_COLOR}"
disk_inode_fy
echo
echo
echo -e "${YELLOW_COLOR}mem_use${BLACK_COLOR}"
mem_use_fy
echo
echo
echo -e "${YELLOW_COLOR}tcp_status${BLACK_COLOR}"
tcp_status_fy
echo
echo
echo -e "${YELLOW_COLOR}cpu_top10${BLACK_COLOR}"
cpu_top10_fy
echo
echo
echo -e "${YELLOW_COLOR}mem_top10${BLACK_COLOR}"
mem_top10_fy
echo -e "${YELLOW_COLOR}traffic${BLACK_COLOR}"
traffic_fy
相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
2月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
384 9
|
2月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
247 2
|
5月前
|
Shell
Shell脚本循环控制:shift、continue、break、exit指令
使用这些命令可以让你的Shell脚本像有生命一样动起来。正确使用它们,你的脚本就能像一场精心编排的舞蹈剧目,既有旋律的起伏,也有节奏的跳跃,最终以一场惊艳的表演结束。每一个动作、每一个转折点,都准确、优雅地完成所需要表达的逻辑。如此,你的脚本不只是冰冷的代码,它透过终端的界面,跳着有节奏的舞蹈,走进观众——使用者的心中。
234 60
|
2月前
|
数据采集 监控 Shell
无需Python:Shell脚本如何成为你的自动化爬虫引擎?
Shell脚本利用curl/wget发起请求,结合文本处理工具构建轻量级爬虫,支持并行加速、定时任务、增量抓取及分布式部署。通过随机UA、异常重试等优化提升稳定性,适用于日志监控、价格追踪等场景。相比Python,具备启动快、资源占用低的优势,适合嵌入式或老旧服务器环境,复杂任务可结合Python实现混合编程。
|
8月前
|
关系型数据库 MySQL Shell
MySQL 备份 Shell 脚本:支持远程同步与阿里云 OSS 备份
一款自动化 MySQL 备份 Shell 脚本,支持本地存储、远程服务器同步(SSH+rsync)、阿里云 OSS 备份,并自动清理过期备份。适用于数据库管理员和开发者,帮助确保数据安全。
|
4月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
456 1
|
6月前
|
存储 Unix Shell
确定Shell脚本在操作系统中的具体位置方法。
这对于掌握Linux的文件系统组织结构和路径方面的理解很有帮助,是我们日常工作和学习中都可能使用到的知识。以上讲解详细清晰,应用简便,是每一个想要精通操作系统的计算机爱好者必备的实用技能。
155 17
|
6月前
|
Linux Shell
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
175 4
|
6月前
|
Linux Shell 数据安全/隐私保护
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
Centos或Linux编写一键式Shell脚本创建用户、组、目录分配权限指导手册
355 3
|
7月前
|
Linux Shell
在Linux、CentOS7中设置shell脚本开机自启动服务
以上就是在CentOS 7中设置shell脚本开机自启动服务的全部步骤。希望这个指南能帮助你更好地管理你的Linux系统。
587 25