shell脚本通过采集ssh连通性、端口监听、网络连接等信息生成graphviz dot文件,再调用dot渲染为png/svg拓扑图,全程离线运行,支持自动刷新与颜色分层标注。

没有监控面板时,用 Shell 脚本生成动态系统拓扑状态图,核心思路是:用命令自动采集节点关系(如 SSH 连通性、进程监听、网络连接、服务依赖),再转换为 Graphviz(dot)格式,最后调用 dot 渲染为 PNG/SVG。整个过程无需 Web 服务或数据库,纯命令行驱动,适合离线环境、跳板机或轻量巡检。
一、自动发现节点连接关系
拓扑图的基础是“谁连了谁”。Shell 脚本可组合以下命令获取实时连接信息:
-
ss -tunap或netstat -tulnp:查本机监听端口及对应进程(识别服务角色,如 nginx、redis-server) -
lsof -i -n -P:查进程打开的网络连接(含远程 IP/端口,识别主动外连关系) -
ping -c1 -W1 $ip &>/dev/null && echo "$ip up":批量探测可达节点(如内网主机列表) -
ssh -o ConnectTimeout=2 -o BatchMode=yes $host 'echo ok' 2>/dev/null:验证 SSH 可达性,推断管理拓扑
建议将常用节点(如数据库、API 网关、缓存)预定义在数组中,脚本循环探测并记录双向关系,避免全网扫描。
二、用 Shell 构建 dot 描述文件
Graphviz 的 .dot 文件本质是文本。Shell 可直接拼接生成,例如:
#!/bin/bash
echo "digraph system_topo {"
echo " rankdir=LR;"
echo " node [shape=box, style=filled, fontsize=10];"
<h1>本机作为中心节点</h1><p>hostname=$(hostname -s)
echo " \"$hostname\" [fillcolor=lightblue];"</p><h1>添加已知服务节点(带颜色区分)</h1><p>echo " \"db01\" [fillcolor=lightcoral];"
echo " \"cache01\" [fillcolor=gold];"</p><h1>根据探测结果添加边(仅当连通时)</h1><p>if ssh -o ConnectTimeout=1 -o BatchMode=yes db01 'true' 2>/dev/null; then
echo " \"$hostname\" -> \"db01\" [label=\"SSH/DB\"];"
fi</p><p>if ss -tun | grep ':6379' >/dev/null; then
echo " \"$hostname\" -> \"cache01\" [label=\"Redis client\"];"
fi</p><p>echo "}"
</p>
输出保存为 topo.dot,后续交给 dot 处理。
三、自动化渲染与更新
安装 Graphviz(apt install graphviz 或 yum install graphviz),然后一行命令生成图片:
-
dot -Tpng topo.dot -o topo.png→ 输出 PNG(适合终端查看或邮件附件) -
dot -Tsvg topo.dot -o topo.svg→ 输出 SVG(可缩放,适合嵌入 HTML 报告)
加个简单循环,每 60 秒刷新一次:
while true; do ./gen_topo.sh > topo.dot dot -Tpng topo.dot -o topo.png 2>/dev/null echo "$(date): updated topo.png" sleep 60 done
搭配 watch -n 60 'ls -lh topo.png' 或用 feh topo.png(Linux 图形终端)即可实现“动态”查看。
四、增强可读性的实用技巧
让生成的图更贴近运维直觉:
-
颜色编码:用
fillcolor区分角色(蓝色=应用,红色=数据库,绿色=缓存) -
标签精简:用
label="HTTP→80"替代冗长端口名,避免图面杂乱 -
分组逻辑:用
subgraph cluster_db { label="Database Layer"; ... }划分子网或层级 -
异常高亮:若某节点探测失败,设
color=red, penwidth=3提示中断
不复杂但容易忽略:每次生成前清空旧 dot 文件头尾,避免重复写入导致语法错误;用 set -e 让脚本在关键命令失败时退出,防止生成无效图。











