通过SNMP批量提取思科交换机端口状态的脚本编写求助
思科交换机批量端口状态检查脚本实现
你之前写的脚本问题很明确:直接把整段别名、整段状态文本抓出来,没有按端口索引做关联匹配,自然没法一一对应,另外还存在community拼写错误、无法识别带空格的别名、没有过滤空别名的问题。
下面是可以直接用的实现方案:
实现逻辑
- 逐行读取交换机列表文件,自动跳过空行、#开头的注释行
- 对每台交换机先拉取端口别名数据,以端口索引为键存入关联数组,直接过滤别名为空的条目,减少无效计算
- 再拉取端口运行状态数据,按端口索引匹配对应别名,将
up(1)/down(2)格式的返回值转换为纯up/down文本 - 按要求的格式输出结果,统一写入结果文件
- 加了SNMP超时配置,遇到离线设备不会长时间卡住
完整脚本
#!/bin/bash # 可根据实际情况修改配置 COMMUNITY="mycommunity" SNMP_TIMEOUT=2 RESULT_FILE="port_check_result.txt" SWITCH_LIST=$1 # 参数校验 if [ -z "$SWITCH_LIST" ] || [ ! -f "$SWITCH_LIST" ]; then echo "使用方法: $0 交换机列表文件路径" exit 1 fi # 清空历史结果 > "$RESULT_FILE" while read -r switch || [ -n "$switch" ]; do # 跳过空行、注释行 [[ -z "$switch" || "$switch" =~ ^# ]] && continue echo "正在处理设备: $switch" # 定义关联数组存 端口索引->别名 映射 declare -A alias_map # 解析别名数据 while IFS= read -r line; do if [[ $line =~ ifAlias\.([0-9]+)\ =\ STRING:\ ?(.*)$ ]]; then idx=${BASH_REMATCH[1]} alias=${BASH_REMATCH[2]} # 仅保留非空别名 [ -n "$alias" ] && alias_map[$idx]="$alias" fi done < <(snmpwalk -v 2c -c "$COMMUNITY" -t $SNMP_TIMEOUT "$switch" .1.3.6.1.2.1.31.1.1.1.18 2>/dev/null) # 解析状态数据并匹配输出 while IFS= read -r line; do if [[ $line =~ ifOperStatus\.([0-9]+)\ =\ INTEGER:\ (up|down) ]]; then idx=${BASH_REMATCH[1]} status=${BASH_REMATCH[2]} # 仅输出有非空别名的端口 if [ -n "${alias_map[$idx]}" ]; then echo "$switch interface \"${alias_map[$idx]}\" is $status" >> "$RESULT_FILE" fi fi done < <(snmpwalk -v 2c -c "$COMMUNITY" -t $SNMP_TIMEOUT "$switch" .1.3.6.1.2.1.2.2.1.8 2>/dev/null) unset alias_map done < "$SWITCH_LIST" echo "处理完成,结果已保存到 $RESULT_FILE"
使用方法
- 将脚本保存为
port_check.sh,执行chmod +x port_check.sh赋予执行权限 - 准备交换机列表文件,每行写一个交换机的管理IP/主机名,支持写#开头的注释
- 执行命令:
./port_check.sh 你的交换机列表文件路径 - 执行完成后,结果会存在当前目录下的
port_check_result.txt中
注意事项
- 你之前测试脚本里的SNMP community拼写错误,
mycomunity正确拼写为mycommunity,否则会出现SNMP认证失败 - 脚本用正则提取端口索引和字段,即使别名包含空格(比如样例里的
Time Clock、Intercom Office)也能正确解析,比你之前用grep截取最后一个字段的方式兼容性好 - 所有SNMP错误输出(比如设备离线、超时)都会被丢弃,不会污染最终结果文件
内容的提问来源于stack exchange,提问作者laurencew
相关产品推荐
相关产品推荐

