如何使用BASH编写类似TOP的动态刷新设备监控程序?
在BASH中实现类似top的动态内容刷新效果
嘿,这个需求我太熟悉了!要做一个像top那样能动态刷新、新内容直接覆盖旧内容的监控工具,BASH里有好几种靠谱的方法,我给你一步步拆解:
方法1:用tput命令(跨终端兼容性最佳)
tput是专门用来控制终端行为的工具,能帮你精准定位光标位置,避免不必要的全量清屏。核心思路是:每次刷新前把光标移回屏幕左上角,然后重新输出所有内容,新内容自然就会覆盖旧的。
举个可直接运行的示例脚本:
#!/bin/bash # 捕获Ctrl+C,退出时恢复终端光标显示 trap 'tput cnorm; exit' INT # 隐藏光标(可选,让刷新过程更顺滑,避免光标闪烁) tput civis while true; do # 把光标移到屏幕左上角(行0,列0) tput cup 0 0 # 输出你的监控内容,这里模拟CPU、内存和时间信息 echo "=== 设备监控工具 ===" echo "CPU使用率: $(top -bn1 | grep 'Cpu(s)' | sed 's/.*, *\([0-9.]*\)%* id.*/\1/' | awk '{print 100 - $1}')%" echo "内存使用率: $(free | grep Mem | awk '{print $3/$2 * 100.0}' | cut -c1-5)%" echo "当前时间: $(date +"%Y-%m-%d %H:%M:%S")" # 每隔1秒刷新一次,可根据需求调整间隔 sleep 1 done
这里的tput civis用来隐藏光标,trap语句是个小细节——确保你用Ctrl+C退出脚本时,终端光标能恢复显示,不然光标会消失哦。
方法2:用ANSI转义序列(更简洁轻量)
如果你的终端支持ANSI控制码(现在绝大多数终端都支持),可以直接输出转义字符来控制光标,不需要依赖tput。常用的两个转义码:
\033[H:把光标移到屏幕左上角\033[J:清除从光标位置到屏幕末尾的所有内容
示例脚本如下:
#!/bin/bash # 捕获Ctrl+C,退出时恢复光标 trap 'echo -e "\033[?25h"; exit' INT # 隐藏光标 echo -e "\033[?25l" while true; do # 回到左上角并清除后续内容 echo -e "\033[H\033[J" # 输出监控内容,这里模拟磁盘和进程数信息 echo "=== 简易设备监控 ===" echo "磁盘使用率: $(df -h / | grep / | awk '{print $5}')" echo "当前进程数: $(ps aux | wc -l)" echo "刷新时间: $(date +"%H:%M:%S")" sleep 1 done
这种方法代码更短,适合快速实现,效果和tput几乎一致。
方法3:用watch命令(适合快速原型验证)
如果你的监控逻辑已经是一个独立的命令或脚本,用watch可以省掉自己写循环的麻烦:
# 每隔1秒执行一次监控脚本,-t参数去掉默认的标题栏 watch -t -n 1 ./your_monitor_script.sh
不过watch的灵活性稍差,比如没法自定义固定表头和动态数据的分区刷新,适合简单场景快速验证需求。
一些实用小技巧
- 分区刷新:如果有固定的表头,不需要每次都重新输出,可以用
tput cup把光标定位到数据区域的起始行,只刷新动态数据部分,效率更高。 - 避免滚动:确保你的输出内容不超过终端行数,不然会出现滚动条破坏覆盖效果。可以用
tput lines获取终端行数,控制输出内容的长度。 - 响应键盘输入:如果需要让脚本支持按q退出等操作,可以在循环里加
read -t 0.1 -n 1检测输入,避免sleep阻塞操作响应。
内容的提问来源于stack exchange,提问作者user3395707
相关产品推荐
相关产品推荐

