当前位置: 首页 > news >正文

一键掌控三线资源:极简 Shell 脚本实现 CPU·磁盘·内存可视化巡检

目录

前言

数值型 for 循环

语法格式

示例:打印 1 到 5

示例:打印5次Hello World

示例:计算 1 到 100 的累加和

遍历型 for 循环

语法格式

示例:遍历字符串列表

示例:遍历数组

示例:遍历文件列表

示例:这边会给一个IP地址的文件(ipddr.txt)需要 ping 文件中的IP(主机)判断是否能通

示例:统计 /var/log 有多少个文件,并且显示这些文件名

示例:需要ping 通 某个网段  机器  并且 输出 通和不通 反馈结果

示例:九九乘法表

while循环

条件判断型

典型示例

示例:实时监控httpd的运行状态

基本语法

case循环

快速示例

实用技巧

示例:设置系统开机、关机和重启

示例:用 case 编写一个查看  cpu   内存  硬盘 资源使用情况

总结

前言

在信息化高速发展的今天,服务器与终端设备的稳定运行已成为企业业务连续性的命脉。面对日益复杂的系统环境,运维人员需要随时掌握 CPU、磁盘、内存三大核心资源的实时状态,以便在性能瓶颈或故障萌芽阶段即可精准干预。然而,传统命令行工具虽然功能强大,却存在记忆负担高、操作路径长、输出可读性差等问题,极易在紧急排障时贻误战机。为此,我们设计了一款轻量级 Shell 交互脚本,将 top、df、free 等底层指令封装成一键式菜单,既保留原生命令的详尽数据,又通过友好提示与编号选择显著降低使用门槛。脚本遵循 POSIX 标准,兼容绝大多数 Linux 发行版,可直接运行于生产服务器、容器或虚拟机,真正做到了“开箱即用”。接下来,让我们一起体验它在日常巡检中所带来的效率跃升。


数值型 for 循环

语法格式

bash

复制

for ((初始值; 限制条件; 步长))
do循环体代码
done
  • 初始值:循环变量的初始值。

  • 限制条件:循环继续执行的条件。

  • 步长:每次循环后循环变量的增量或减量。

示例:打印 1 到 5

bash

复制

#!/bin/bashfor ((i=1; i<=5; i++))
doecho "当前数字: $i"
done

输出结果:

复制

当前数字: 1
当前数字: 2
当前数字: 3
当前数字: 4
当前数字: 5

示例:打印5次Hello World

# shell脚本
for ((i=0;i<5;i++))
doecho "$i - Hello World"
done# 测试
[root@localhost shelldemo]# sh dome8.sh 
0 - Hello World
1 - Hello World
2 - Hello World
3 - Hello World
4 - Hello World

示例:计算 1 到 100 的累加和

bash

复制

#!/bin/bashcount=0
for((i=0;i<=100;i++))
docount=$(($count + $i));
doneecho "累加的结果是:${count}";# 测试
[root@localhost shelldemo]# sh dome9.sh 
累加的结果是:5050

输出结果:

1 到 10 的累加和为: 55


遍历型 for 循环

语法格式

bash

复制

for 变量名 in 数据1 数据2 数据3 ...
do循环体代码
done
  • 变量名:依次取数据集合中的每个值。

  • 数据集合:可以是显式列出的数据,也可以是数组、命令输出等。

示例:遍历字符串列表

bash

复制

#!/bin/bashfor animal in cat dog elephant
doecho "动物名称: $animal"
done

输出结果:

复制

动物名称: cat
动物名称: dog
动物名称: elephant

示例:遍历数组

bash

复制

#!/bin/bashmy_array=(A B C D)for element in ${my_array[@]}
doecho "数组元素: $element"
done

输出结果:

复制

数组元素: A
数组元素: B
数组元素: C
数组元素: D

示例:遍历文件列表

bash

复制

#!/bin/bashfor file in $(ls /root/shelldemo)
doecho "文件名: $file"
done

输出结果:

复制

文件名: file1.sh
文件名: file2.sh
文件名: file3.sh

示例:这边会给一个IP地址的文件(ipddr.txt)需要 ping 文件中的IP(主机)判断是否能通

# shell脚本
HT_IP=$(< ./ip.txt)
#for循环
for ip in $HT_IP
#ping
doping -c 3 -i 0.5 -W 2 $ip &>/dev/nullif [ $? -eq 0 ]; thenecho "$ip is up"elseecho "$ip is down"fi
#输出结果
done# 测试
[root@localhost shelldemo]# sh dome10.sh 
192.168.10.101 is up
192.168.10.102 is down
192.168.10.103 is down
192.168.10.104 is down
192.168.10.105 is down
192.168.10.106 is up
192.168.10.1 is up

示例:统计 /var/log 有多少个文件,并且显示这些文件名

# shell脚本
# 将所有的文件列表用一个变量手记起来
file_list=$(ls -r /var/log/*);
count= 0
# for遍历,判断是否存在文件
for file in $file_list
# 如果存在的话,+1,并打印
doif [ -f $file ]; thenecho "$file是一个文件"let count++	fi
doneecho "/var/log文件夹下面一共有$count个文件"# 测试
[root@localhost shelldemo]# sh dome10.sh 
192.168.10.101 is up
192.168.10.102 is down
192.168.10.103 is down
192.168.10.104 is down
192.168.10.105 is down
192.168.10.106 is up
192.168.10.1 is up
[root@localhost shelldemo]# vim dome10.sh
[root@localhost shelldemo]# vim dome11.sh
[root@localhost shelldemo]# chmod +x dome11.sh
[root@localhost shelldemo]# sh dome11.sh 
dome11.sh:行3: 0: 未找到命令
/var/log/yum.log是一个文件
/var/log/Xorg.9.log是一个文件
/var/log/Xorg.0.log.old是一个文件
/var/log/Xorg.0.log是一个文件
/var/log/wtmp是一个文件
/var/log/wpa_supplicant.log是一个文件
/var/log/vmware-vmtoolsd-root.log是一个文件
/var/log/vmware-vmsvc-root.log是一个文件
/var/log/vmware-vgauthsvc.log.0是一个文件
/var/log/vmware-network.log是一个文件
/var/log/vmware-network.9.log是一个文件
/var/log/vmware-network.8.log是一个文件
/var/log/vmware-network.7.log是一个文件
/var/log/vmware-network.6.log是一个文件
/var/log/vmware-network.5.log是一个文件
/var/log/vmware-network.4.log是一个文件
/var/log/vmware-network.3.log是一个文件
/var/log/vmware-network.2.log是一个文件
/var/log/vmware-network.1.log是一个文件
/var/log/tallylog是一个文件
/var/log/spooler-20250827是一个文件
/var/log/spooler-20250817是一个文件
/var/log/spooler-20250810是一个文件
/var/log/spooler是一个文件
/var/log/secure-20250827是一个文件
/var/log/secure-20250817是一个文件
/var/log/secure-20250810是一个文件
/var/log/secure是一个文件
/var/log/mysqld.log是一个文件
/var/log/messages-20250827是一个文件
/var/log/messages-20250817是一个文件
/var/log/messages-20250810是一个文件
/var/log/messages是一个文件
/var/log/maillog-20250827是一个文件
/var/log/maillog-20250817是一个文件
/var/log/maillog-20250810是一个文件
/var/log/maillog是一个文件
/var/log/lastlog是一个文件
/var/log/grubby_prune_debug是一个文件
/var/log/firewalld是一个文件
/var/log/dmesg.old是一个文件
/var/log/dmesg是一个文件
/var/log/cron-20250827是一个文件
/var/log/cron-20250817是一个文件
/var/log/cron-20250810是一个文件
/var/log/cron是一个文件
/var/log/btmp是一个文件
/var/log/boot.log-20250830是一个文件
/var/log/boot.log-20250829是一个文件
/var/log/boot.log-20250827是一个文件
/var/log/boot.log-20250817是一个文件
/var/log/boot.log-20250816是一个文件
/var/log/boot.log-20250815是一个文件
/var/log/boot.log-20250814是一个文件
/var/log/boot.log是一个文件
/var/log文件夹下面一共有55个文件

示例:需要ping 通 某个网段  机器  并且 输出 通和不通 反馈结果

# shell脚本
# 交互式写一个网段
read -p "检查网段:" ip
# ping一下
ping -c 3 -i 0.5 -W 1 $ip >/dev/null 2>&1
# 用if判断
if [ $? -eq 0 ]; thenecho "$ip可以ping通">>ping.txt
elseecho "$ip不可以ping通">>ping.txt
fi# 测试
# 192.168.66.12不可能连接通
[root@localhost shelldemo]# sh dome12.sh 
检查网段:192.168.66.12
[root@localhost shelldemo]# cat ping.txt
192.168.10.106可以ping通
192.168.66.12不可以ping通

示例:九九乘法表

# 遍历i从1到9
for i in $(seq 9);
do
# 遍历j从1到ifor j in $(seq $i);doecho -n "$i*$j=$((i*j)) "doneecho -e "\n"
done# 测试
[root@localhost shelldemo]# sh dome13.sh 
1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81 

示例:随机生成一个15位的密码

# shell脚本
# 随机生成一个10位数的密码
key="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
# 列出key的字符串数目
num=${#key}
# 遍历
for i in $(seq 15); doindex=$[RANDOM%$num]password=$password${key:$index:1}
doneecho "密码是$password"# 测试
[root@localhost shelldemo]# sh dome14.sh 
密码是aMcDjfRetHA2Wi1
[root@localhost shelldemo]# sh dome14.sh 
密码是sZdzcxaLMzUAnis
[root@localhost shelldemo]# sh dome14.sh 
密码是4zQTx9YS4kWkBSm

while循环

条件判断型

适合「达到某个条件就停止」的场景。

bash

while [ 条件表达式 ]
do命令# 必须修改循环条件,否则死循环
done

示例:等待用户输入 yes/YES

# shell脚本
while [ "$y" != "yes" -a "$y" != "YES" ]do echo "请输入yes/YES停止循环"read y
doneecho "循环已经停止"# 测试[root@localhost shelldemo]# sh dome15.sh 
请输入yes/YES停止循环
qwerty
请输入yes/YES停止循环
fd
请输入yes/YES停止循环
fghjk
请输入yes/YES停止循环
hgfd
请输入yes/YES停止循环
gfx
请输入yes/YES停止循环
456789
请输入yes/YES停止循环
resw
请输入yes/YES停止循环
9ok,
请输入yes/YES停止循环
fds
请输入yes/YES停止循环
yes
循环已经停止
  1. 数值运算型
    用 Bash 的算术表达式 (( ))let,实现类 C 的循环。

bash

# shell脚本
i=1
while(($i<3))
doecho $ilet i++  # 或者((i++))
done# 测试
[root@localhost shelldemo]# sh dome16.sh 
1
2
  1. 无限循环(死循环)
    需要内部用 breakexit 退出。

bash

while true
doread -p "请输入字符串:" str[ "$str" == "quit" ] && exit 0
done

示例:死循环

# shell脚本
while true 
doecho "请输入字符串:"read yif [ "$y" == "yes" ]; thenexit 0 # 退出fi
done# 测试
[root@localhost shelldemo]# chmod dome17.sh 
chmod: "dome17.sh" 后缺少操作数
Try 'chmod --help' for more information.
[root@localhost shelldemo]# chmod +x dome17.sh 
[root@localhost shelldemo]# sh dome17.sh 
请输入字符串:
sdfg
请输入字符串:
xcv
请输入字符串:
oiug
请输入字符串:
cv
请输入字符串:
456
请输入字符串:
poih
请输入字符串:
xf
请输入字符串:
yea^Hs^H^[[3~^H
请输入字符串:
yes                    # 已退出

典型示例

  1. 计算 1…10 累加和

bash

count=0
num=1
while (( num <= 10 ))
docount=$(( count + num ))((num++))
done
echo "1-10 累加和:$count"
  1. 猜数字游戏(节选 while 片段)

num=$[RANDOM%100+1]
while true
doread -p "猜 1-100 的数:" caiif [ $cai -eq $num ]; thenecho "恭喜,猜对了!"exit 0elif [ $cai -gt $num ]; thenecho "猜大了"elseecho "猜小了"fi
done

示例:实时监控httpd的运行状态

# shell脚本
while ps -aux|grep httpd|grep -v grep &>/dev/null
doecho "httpd正在运行"sleep 2	
doneecho "httpd不在运行"# 测试
# 此时httpd开启
[root@localhost shelldemo]# sh dome20.sh
httpd正在运行
httpd正在运行
httpd正在运行
httpd正在运行
httpd正在运行
httpd正在运行
httpd正在运行
httpd正在运行
...
# 此时关闭httpd
[root@localhost shelldemo]# sh dome20.sh
httpd不在运行

基本语法

case $变量 in模式1)命令1;;模式2)命令2;;*)              # 通配符,相当于 default默认命令;;
esac    # 反写 case,表示结束
  • 每个分支必须以右括号 ) 结束。

  • 每个分支命令块以 ;; 结束。

  • 支持通配符:* 匹配任意字符,? 匹配单个字符,| 表示“或”。


case循环

快速示例

bash

#!/bin/bash
case $1 in"hello")echo "Hello World!";;"test")echo "testing...";;"")echo "$0 没有参数";;*)                 # 其余任何输入echo "默认分支";;
esac

运行示例

$ ./demo.sh hello   → Hello World!
$ ./demo.sh test    → testing...
$ ./demo.sh         → ./demo.sh 没有参数
$ ./demo.sh abc     → 默认分支

实用技巧

  1. 多模式匹配

    bash
    case $opt iny|Y|yes|YES) echo "确认" ;;n|N|no|NO)   echo "取消" ;;
    esac
  2. 模式里可包含通配符

    bash
    case $filename in*.tar.gz)  tar -zxf "$filename" ;;*.zip)     unzip "$filename" ;;
    esac
  3. read 搭配做简单菜单

    bash
    read -p "选择操作[start|stop|restart]: " action
    case $action instart)  systemctl start nginx ;;stop)   systemctl stop  nginx ;;restart)systemctl restart nginx ;;*)      echo "未知操作" ;;
    esac

示例:设置系统开机、关机和重启

# shell脚本
case $1 in
"start")
systemctl start httpd.service
echo "服务已开启"
;;"stop")
systemctl stop httpd.service
echo "服务已关闭"
;;"restart")
systemctl stop httpd.service
systemctl start httpd.service
echo "服务已重启"
;;*)
echo "服务不存在,请输入正确的服务 start stop restart"
;;
esac

测试结果:

[root@localhost shelldemo]# sh dome18.sh start
服务已开启
[root@localhost shelldemo]# systemctl status httpd
● httpd.service - The Apache HTTP ServerLoaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)Active: active (running) since 六 2025-08-30 16:50:18 CST; 12s agoDocs: man:httpd(8)man:apachectl(8)Main PID: 10702 (httpd)Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"Tasks: 6CGroup: /system.slice/httpd.service├─10702 /usr/sbin/httpd -DFOREGROUND├─10706 /usr/sbin/httpd -DFOREGROUND├─10707 /usr/sbin/httpd -DFOREGROUND├─10708 /usr/sbin/httpd -DFOREGROUND├─10709 /usr/sbin/httpd -DFOREGROUND└─10710 /usr/sbin/httpd -DFOREGROUND8月 30 16:50:18 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
8月 30 16:50:18 localhost.localdomain httpd[10702]: AH00558: httpd: Could not reliably determine the server's fully qualifie...ssage
8月 30 16:50:18 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost shelldemo]# sh dome18.sh stop
服务已关闭
[root@localhost shelldemo]# systemctl status httpd.service 
● httpd.service - The Apache HTTP ServerLoaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)Active: inactive (dead)Docs: man:httpd(8)man:apachectl(8)8月 30 16:50:18 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
8月 30 16:50:18 localhost.localdomain httpd[10702]: AH00558: httpd: Could not reliably determine the server's fully qualifie...ssage
8月 30 16:50:18 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
8月 30 16:50:38 localhost.localdomain systemd[1]: Stopping The Apache HTTP Server...
8月 30 16:50:39 localhost.localdomain systemd[1]: Stopped The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost shelldemo]# sh dome18.sh asdfghj
服务不存在,请输入正确的服务 start stop restart

示例:用 case 编写一个查看  cpu   内存  硬盘 资源使用情况

# shell脚本
# 提示查看用户信息
echo "请查看用户信息"
echo "1.CPU的使用情况"
echo "2.磁盘的使用情况"
echo "3.内存的使用情况"
echo "4.退出"
# 用户交互
read -p "请输入选项1、2、3、4:" de
# case语句
case $de in
"1")
top -bn1|grep Cpu
;;"2")
df -h
;;"3")
free -m
;;"4")
exit 0
;;*)
echo "请输入正确的设备1、2、3、4"
;;esac# 运行
[root@localhost shelldemo]# sh dome22.sh 
请查看用户信息
1.CPU的使用情况
2.磁盘的使用情况
3.内存的使用情况
4.退出
请输入选项1、2、3、4:1
%Cpu(s):  1.9 us, 20.8 sy,  0.0 ni, 77.4 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
[root@localhost shelldemo]# sh dome22.sh 
请查看用户信息
1.CPU的使用情况
2.磁盘的使用情况
3.内存的使用情况
4.退出
请输入选项1、2、3、4:3total        used        free      shared  buff/cache   available
Mem:           3770        1273         819          49        1677        2207
Swap:          3967           0        3967
[root@localhost shelldemo]# sh dome22.sh 
请查看用户信息
1.CPU的使用情况
2.磁盘的使用情况
3.内存的使用情况
4.退出
请输入选项1、2、3、4:4

总结

通过上述脚本实践,我们深刻体会到“简单即是力量”的运维哲学:只需三十余行代码,便能把晦涩的系统指标转化为清晰易读的管理视图。用户仅需输入 1、2、3、4 即可在 CPU 负载、磁盘容量、内存占用与程序退出之间自由切换,无需再背冗长参数,也不必担心误操作带来的风险。脚本在真实环境中已验证可行,输出格式与系统原生工具保持一致,方便直接粘贴到监控平台或故障工单。未来可进一步扩展:加入循环菜单实现连续查询、用颜色高亮关键阈值、将结果重定向到日志文件,甚至结合 cron 定时执行,实现无人值守巡检。希望这段示例能为正在构建自动化运维体系的同行提供灵感,也期待社区共同迭代,让 Shell 脚本在 DevOps 时代继续焕发活力。

http://www.xdnf.cn/news/1404505.html

相关文章:

  • SRE命令行兵器谱之二:lsof - 解密“端口被占用”与“文件句柄泄漏”的终极侦探
  • MySQL-事务(下)-MySQL事务隔离级别与MVCC
  • 2021-11-10 C++不变初心数
  • ans1语法的一个例子nt5inf.cat
  • 详解Vue2、Vue3与React的Diff算法
  • TuringComplete游戏攻略(2.2存储器)
  • spark.sparkContext.broadcast() 与 org.apache.spark.sql.functions.broadcast 的区别
  • Docker实战避坑指南:从入门到精通
  • 神经网络激活函数:从ReLU到前沿SwiGLU
  • 分分合合,门模块方案又兴起了
  • 用更少的数据识别更多情绪:低资源语言中的语音情绪识别新方法
  • Vue生命周期、工程化开发和脚手架、组件化开发
  • hubert模型代码分析
  • 聚中原·贸全国·达世界,2026郑州台球展8月15至17举办
  • 深入解析Nginx常见模块1
  • 世界模型的典型框架与分类
  • 如何提高存储过程的可维护性
  • wav2vec2.0模型代码分析
  • vite Rendering 10 pagesReferenceError: document is not defined
  • OpenCV 图像形态学操作与边缘检测实战指南
  • 深刻理解软硬件链接
  • 【MogDB】在刚发布的银河麒麟v11上安装MogDB
  • Unity游戏打包——GooglePlay手动传包
  • 微服务架构中的 “双保险“:服务保护与分布式事务解决方案实战
  • 配置vsc可用的C语言环境
  • 【开题答辩全过程】以 基于WEB的茶文化科普系统的设计与实现为例,包含答辩的问题和答案
  • AI融合高等教育:从通识到专业 - 学科+AI人才培养白皮书(下)
  • 防火墙技术(三):状态检测和会话机制
  • SQLSERVER分组
  • Cocos游戏中自定义按钮组件(BtnEventComponent)的详细分析与实现