You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:18:27