本文共 7716 字,大约阅读时间需要 25 分钟。
select循环是一种在shell脚本中用户交互选择项的常用方法。与简单的echo读取不同,select循环可以让用户逐步输入选择,直到确定退出。
以下是一个典型的select循环示例:
#!/usr/bin/bash PS3="Your choice is [5 for quit]:" select choice in disk_partition filesystem cpu_load mem_util quit do case "$choice" in disk_partition) fdisk -l ;; filesystem) df -h ;; cpu_load) uptime ;; mem_util) free -m ;; quit) break ;; *) echo "error" exit esac done
执行效果如图所示:
在shell环境中,$PS1、$PS2和$PS3分别表示提示符的三个状态。默认情况下:
jiwangreal@ubuntu:~$ echo $PS1 [\e]0;\u@\h: \w\a\]${ debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$ $PS3可以通过修改修改提示符,如下所示:
该脚本旨在分析系统资源的性能瓶颈,功能包括:
脚本开始时会判断OS类型:
os_check(){ if [ -e /etc/redhat-release ];then REDHAT=`cat /etc/redhat-release| cut -d' ' -f1` else DEBIAN=`cat /etc/issue|cut -d' ' -f1` fi if [ "$REDHAT" == "CentOS" -o "$REDHAT" == "Red" ];then P_M=yum elif [ "$DEBIAN" == "Ubuntu" -o "DEBIAN" == "ubuntu" ];then P_M=apt-get else OS not support exit 1 fi } 如果需要安装额外工具(如vmstat或iostat),脚本会自动判断并安装。
主循环体内,用户可以选择不同的选项进行分析:
while true:do select input in cpu_load disk_load disk_use disk_inode mem_use tcp_status cpu_top10 mem_top10 traffic quit do case $input in cpu_load) # CPU利用率与负载 i=1 while [[ $i -le 3 ]];do echo -e "\033[32m 参考值${i}\033[0m" UTIL=`vmstat | awk '{if(NR==3) print 100-$15"%"}'` USER=`vmstat | awk '{if(NR==3) print $13"%"}'` SYS=`vmstat | awk '{if(NR==3) print $14"%"}'` IOWAIT=`vmstat | awk '{if(NR==3) print $16"%"}'` echo "Utile: $UTIL" echo "User user:$USER" echo "System use: $SYS" echo "I/O wait: $IOWAIT" let i++ sleep 1 done echo "--------------------------" break ;; disk_load) # 硬盘I/O负载 i=1 while [[ $i -le 3 ]];do echo -e "\033[32m 参考值${i}\033[0m" UTIL=`iostat -x -k | awk '/^[v|s]/{OFS=": ";print $1,$NF"%"}'` READ=`iostat -x -k | awk '/^[v|s]/{OFS=": ";print $1,$6"KB"}'` WRITE=`iostat -x -k | awk '/^[v|s]/{OFS=": ";print $1,$7"KB"}'` IOWAIT=`vmstat | awk '{if(NR==3) print $16"%"}}'` echo -e "Util:" echo -e "${UTIL}" echo "I/O wait: $IOWAIT" echo "I/O Wait: $IOWAIT" echo "Read/s: \n$READ" echo "Write/s: \n$WRITE" i=$(($i+1)) sleep 1 done echo "--------------------------" break ;; disk_use) # 硬盘利用率 DISK_LOG=/tmp/disk_use.tmp DISK_TOTAL=`fdisk -l | awk '/^Disk.*bytes/ && /\/dev/{printf $2" ";printf "%d", $3;print "GB"}'` USE_RATE=`df -h | awk '/^\/dev/{print int($5)}'` for i in $USE_RATE;do if [ $i -gt 90 ];then PART=`df -h|awk '{if(int($5) === ''$i'') print $6}'` echo "$PART = ${i}%" >> $DISK_LOG fi done echo "--------------------------" echo -e "Dick toltal:\n${DISK_TOTAL}" if [ -f $DISK_LOG ];then echo "--------------------------" cat $DISK_LOG echo "--------------------------" rm -f $DISK_LOG else echo "--------------------------" echo "Disk use rate no than 90% of the partition" echo "--------------------------" fi break ;; disk_inode) # 硬盘inode利用率 INODE_LOG=/tmp/inode_use.tmp INODE_USE=`df -i | awk '/^\dev/{print int($5)}'` for i in $INODE_USE;do if [ $i -gt 90 ];then PART=`df -h|awk '{if(int($5) == ''$i'') print $6}'` echo "$PART = ${i}%" >> $INODE_LOG fi done if [ -f $INODE_LOG ];then echo "--------------------------" cat $INODE_LOG echo "--------------------------" rm -f $INODE_LOG else echo "--------------------------" echo "Disk use rate no than 90% of the partition" echo "--------------------------" fi break ;; mem_use) # 内存利用率 MEM_TOTAL=`free -m|awk '{if(NR==2)printf "%.1f" ,$2/1024} END{print "G"}'` USE=`free -m|awk '{if(NR==2)printf "%.1f" ,$3/1024} END{print "G"}'` FREE=`free -m|awk '{if(NR==2)printf "%.1f" ,$4/1024} END{print "G"}'` CACHE=`free -m|awk '{if(NR==2)printf "%.1f" ,$6/1024} END{print "G"}'` echo -e "Total: $MEM_TOTAL" echo -e "Use:$USE" echo -e "Free : $FREE" echo -e "Cache: $CACHE" echo "--------------------------" break ;; tcp_status) # 网络连接状态 COUNT=`ss -ant|awk '!/State/{status[$1]++}END{for(i in status) print i,status[i]}'` echo -e "TCP connection status:\n$COUNT" echo "--------------------------" break ;; cpu_top10) # 占用CPU高的前10个进程 CPU_LOG=/tmp/cpu_top.tmp 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 if [[ -n `cat $CPU_LOG` ]];then echo -e "\033[32m 参考值${i}\033[0m" cat $CPU_LOG >> $CPU_LOG ## 将文件清空 else echo "No process using the CPU" break fi let i++ sleep 1 done echo "--------------------------" break ;; mem_top10) # 占用内存高的前10个进程 MEM_LOG=/tmp/mem_top.tmp i=1 while [[ $i -le 3 ]];do ps aux|awk '{if(($3>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 "\033[32m 参考值${i}\033[0m" cat $MEM_LOG >> $MEM_LOG ## 将文件清空 else echo "No process using the Memory" break fi let i++ sleep 1 done echo "--------------------------" break ;; traffic) # 查看网络流量 while true;do read -p "Please enter the network card name(eth[0-9]) or em[0-9]: " eth if [ `ifconfig`| grep -c "\<$eth\>" -eq 1 ];then break else echo "Input format error or Do not have the card name,please input again" fi echo "--------------------------" echo -e "In ------- Out" i=1 while [[ $i -le 3 ]];do OLS_IN=`ifconfig $eth |awk -F'[: ]+' '{/bytes/if(NR==8) print $4;else if(NR==5)print $6}'` OLS_OUT=`ifconfig $eth |awk -F'[: ]+' '{/bytes/if(NR==8) print $9;else if(NR==7)print $6}'` NEW_IN=`ifconfig $eth |awk -F'[: ]+' '{/bytes/if(NR==8) print $4;else if(NR==5)print $6}'` NEW_OUT=`ifconfig $eth |awk -F'[: ]+' '{/bytes/if(NR==8) print $9;else if(NR==7)print $6}'` IN=`awk 'BEGIN{printf "%.1f\n",'$((${ NEW_IN}-${ OLD_IN}))'/1024/128}'` OUT=`awk 'BEGIN{printf "%.1f\n",'$((${ NEW_OUT}-${ OLD_OUT}))'/1024/128}'` echo "${IN}MB/s ${OUT}MB/s" i=$(($i+1)) sleep 1 done echo "--------------------------" break done ;; quit) exit 0 ;; *) echo "--------------------------" echo "Please enter the number" echo "--------------------------" break ;; esac done done 脚本还支持自定义日志文件清空功能,便于持续监控系统状态。
关于脚本中的NR==3处理原因:
在vmstat命令输出中,NR表示当前的行数。由于vmstat通常显示5行,其中第3行包含了重要的系统状态信息(如CPU利用率、用户、系统、I/O等)。因此,脚本中使用NR==3来处理这行数据,以获取具体的性能指标。
关于文件利用率的解释:
每个文件会分配一个inode存储文件的元数据,而实际的文件内容则以块的形式存储在磁盘的数据区。无论是文件的元数据还是实际数据,都会占用磁盘空间。当inode或块都满的时候,磁盘空间就被利用满了。
grep -c的作用:
grep -c是grep命令的一个选项,它用于统计匹配项的数量。如果没有匹配项,grep -c会返回0;如果有匹配项,返回匹配的数量。
为啥要除以128?
网络带宽通常以Mbit/s为单位表示,但实际上可能需要除以8转换成标准的单位(如KB/s或B/s)。例如,家里的1M带宽实际上等于1024Kbit/s,而一个Byte等于8bit。因此,在计算网络流量时,通常需要将流量除以8来得到更标准的单位。
转载地址:http://xufzz.baihongyu.com/