干了七八年网络运维,我最大的感受是:真正让人崩溃的从来不是网络故障本身,而是重复操作太多。几十台交换机上线,一台一台敲命令行,一个 VLAN 一个 VLAN 地加,手一抖还会把接口划错。后来我把日常设备配置和状态巡检逐步改造成了 Shell 脚本批量执行,效率提升是肉眼可见的,原来需要半天的工作量压缩到十几分钟,而且错误率比手工操作低得多。这篇就围绕“Shell 批量配置网络设备、监控网络状态”这个场景,把我在实际运维中总结的脚本思路、执行流程和踩过的坑完整写出来,供同样在跟网络设备死磕的兄弟们参考。
1. 先算一笔账:手工配置网络设备到底贵在哪里
1.1 看得见的时间成本
按一台接入层交换机从零开始上线来算,标准化流程大概是:接 console 线或者通过 SSH 登录设备、清空旧配置、设置设备名和管理 IP、创建 VLAN、配置接口划入对应 VLAN、关闭未用接口、配置 SSH 远程管理、最后保存配置并验证连通性。手速再快,整个过程也要 15 到 20 分钟。
这还只是单台设备。如果是一次园区网改造,几十台上联交换机加百余个接入交换机,纯手工操作意味着连续多天泡在命令行里。我之前统计过一次,配置 50 台接入交换机,纯手工大概需要 12 到 15 个小时。中间还要吃饭、上厕所、被临时电话打断,实际耗时基本要翻倍。而用 Shell 脚本批量化之后,同样的 50 台设备,串行执行大约 20 到 30 分钟就能全部跑完。这还只是配置阶段,后面还有验证阶段,验证同样可以被脚本自动化。
1.2 看不见的风险成本
比时间成本更隐蔽的是风险成本。手工操作时,人的注意力是递减的,配置第 5 台设备时可能还精神抖擞,配置到第 35 台时眼睛已经开始花了。VLAN 编号看错、接口编号打错、掩码多写一位,这类错误几乎无法完全避免。而且设备操作一旦出错,排障的时间往往比配置的时间更长。你要先确认哪台设备出了问题,再登上去看当前配置,对照变更记录排查,过程非常痛苦。
批量脚本在这方面的优势不仅仅是快,更重要的是“每次执行的内容完全一致”。脚本按统一的模板生成配置,每一台设备拿到的命令格式相同,只有变量部分不同。这种一致性让错误率从“人难免手滑”降到了“只要模板对就不会错”。
1.3 Shell 在网络运维中的定位
有人可能会问:做自动化不是有 Ansible 吗?不是有 Nornir 吗?为什么还要用 Shell?
这是我从实际环境出发的理解:Shell 是网络运维自动化最底层的“通用语言”。你写 Ansible 模块,底层本质还是要通过 SSH 连接设备执行命令;你写 Python 脚本,调用 netmiko 或者 paramiko,那也只是封装了连接和命令下发的底层逻辑。Shell 脚本的优势在于它几乎零依赖,任何一台 Linux 服务器上都带 bash,配合 expect、sshpass 这类小工具就能直接操作网络设备。对于中小型网络环境,没有必要为了自动化专门搭建一套 Ansible 控制节点,Shell 脚本轻量、直观、改起来快。
当然,Shell 也有它的短板,比如不适合做大规模的配置审计和状态收敛,这我在后面会专门讨论。但作为网络管理员的日常工具,Shell 的性价比非常高。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 批量配置的核心思路:把交互式会话改造成自动化对话
2.1 设备台账标准化是整个自动化的地基
不管用什么脚本批量配置,前提都是你手里有一份准确的设备清单。很多运维同行上来就写脚本,结果第一轮跑下来一半设备登录失败,回头一查,要么 IP 写错了,要么密码不同,要么设备型号混用导致命令不兼容。这份清单就是设备台账,它的质量直接决定自动化能不能落地。
我的习惯是先维护一个纯文本格式的设备清单,每行代表一台设备,字段用空格或者逗号分隔。比如:
text复制192.168.10.11 接入-3F-A vlan100 uplink=Gi0/24
192.168.10.12 接入-3F-B vlan101 uplink=Gi0/24
192.168.10.13 接入-4F-A vlan102 uplink=Gi0/24
把 IP、设备名、业务 VLAN、上联口这些差异化信息抽出来,脚本只读这份清单,然后逐行生成配置。这样做的好处很直接:以后新增设备,只需要在清单里加一行,不需要动脚本本身。设备台账结构建议包含以下字段:
- 管理 IP 地址
- 设备名称与所在位置
- 设备厂商和型号(用于适配不同命令集)
- 业务 VLAN 或其他配置参数
- 上联接口编号
- 登录凭据的引用信息
实际执行时,脚本会忽略以 # 开头的注释行,方便在清单里写说明。
2.2 expect 脚本实现 SSH 自动登录和命令下发
网络设备和 Linux 主机不一样,登录进去之后是一个交互式 CLI 环境。Shell 脚本本身没办法直接跟交互式程序对话,这时候就要借助 expect。expect 可以理解为一个“会话自动应答器”,它监听程序输出,当匹配到指定的字符串(比如 Password:、>、#)时,自动发送提前定义好的指令。
下面是我实际用过的 expect 配置脚本,简化后大概是这个样子:
expect复制#!/usr/bin/expect
# 批量配置 expect 脚本
# 用法: ./deploy.exp <IP> <设备名> <VLAN>
set timeout 30
set ip [lindex $argv 0]
set name [lindex $argv 1]
set vlan [lindex $argv 2]
set user "admin"
set pass "YourPass"
log_file -a /var/log/netdeploy.log
spawn ssh -o StrictHostKeyChecking=no $user@$ip
expect {
"Password:" { send "$pass\r" }
"yes/no" { send "yes\r"; exp_continue }
timeout { puts "登录超时: $ip"; exit 1 }
}
expect "#"
send "configure terminal\r"
expect "(config)#"
send "hostname $name\r"
expect "(config)#"
send "vlan $vlan\r"
expect "(config-vlan)#"
send "name Client_$vlan\r"
expect "(config-vlan)#"
send "exit\r"
expect "(config)#"
send "interface Gi0/24\r"
expect "(config-if)#"
send "switchport mode trunk\r"
expect "(config-if)#"
send "exit\r"
expect "(config)#"
send "end\r"
expect "#"
send "write memory\r"
expect "#"
send "exit\r"
这里有几个细节值得展开。第一个是 exp_continue 的用法。首次 SSH 连接时经常会出现 host key 确认提示,也就是 yes/no 那个问题。我在 expect 块里同时匹配了 Password: 和 yes/no,一旦匹配到 yes/no 就发送 yes,然后继续等待下一个匹配。这种多分支结构可以一次性处理登录过程中的各种交互分支。
第二个是 log_file。脚本执行过程中所有输出都会被记录到日志文件,这在变更审计时至关重要。哪天设备出了问题,你可以回看日志确认当时脚本到底下发过什么命令。
第三个是命令发送的节奏。网络设备 CLI 不像 Linux Shell 有那么完善的管道和补全机制,某些老设备命令执行很慢。expect 脚本里的 timeout 就是为这种情况准备的。30 秒的超时一般够用,遇到性能很差的设备可以调大到 60 秒,但不要无限等待,否则脚本卡死你都不知道。
2.3 用 Shell 驱动 expect 实现批量轮巡
expect 脚本每次只处理一台设备。要批量处理几十台,就需要用一个外层 Shell 脚本去逐行读取设备清单,循环调用 expect 脚本。这是整套自动化里我在生产环境最常用的形式:
bash复制#!/bin/bash
# 批量配置入口脚本
# 从设备清单读取参数,逐台调用 expect 脚本
EQUIP_LIST="/opt/nettool/equipment.list"
EXPECT_SCRIPT="/opt/nettool/deploy.exp"
SUCCESS_COUNT=0
FAIL_COUNT=0
if [ ! -f "$EQUIP_LIST" ]; then
echo "设备清单不存在: $EQUIP_LIST"
exit 1
fi
echo "========== 批量配置开始: $(date) =========="
# 忽略空行和以 # 开头的注释行
grep -Ev '^\s*#|^\s*$' "$EQUIP_LIST" | while read ip name vlan uplink; do
echo ">>> 正在配置 $name ($ip) VLAN=$vlan"
# expect 脚本返回 0 表示成功,非 0 表示失败
if $EXPECT_SCRIPT "$ip" "$name" "$vlan"; then
echo ">>> $name 配置成功"
SUCCESS_COUNT=$((SUCCESS_COUNT + 1))
else
echo ">>> $name 配置失败"
FAIL_COUNT=$((FAIL_COUNT + 1))
fi
# 每台设备之间停顿 2 秒,避免设备并发处理不过来
sleep 2
done
echo "========== 批量配置结束: $(date) =========="
echo "成功: $SUCCESS_COUNT, 失败: $FAIL_COUNT"
这段脚本特别值得注意的有几点。
第一个是 grep -Ev 过滤逻辑。运维的配置文件里必然有注释和空行,直接用 while read 读取会把注释行也当参数处理,导致脚本试图连接一个叫 # 的主机。这个习惯我强烈建议保留,代价极低,收益很高。
第二个是失败计数。批量脚本最怕的就是跑完了不知道哪些设备成功、哪些失败。我习惯在最终输出里汇总成功和失败数量,同时日志文件里也有完整记录。执行完几十台设备后,一眼就能看出有没有需要人工介入的例外。
第三个是设备之间加 sleep 2。很多人觉得这是浪费时间的操作,但实际网络设备并发处理能力有限。如果两台设备之间的登录间隔太短,部分中低端设备的 SSH 服务可能出现短暂无响应。串行执行虽然慢了一点,但稳定性远高于高并发轮巡。
2.4 变量化配置模板,一套脚本适配不同设备
设备清单里的参数最后要转化为设备命令,怎么转?我采用的思路是“配置模板 + 变量替换”。对于上面的接入交换机标准配置,先把所有设备相同的部分固化成模板,差异部分用占位符代替:
text复制hostname __NAME__
vlan __VLAN__
name Client___VLAN__
interface __UPLINK__
switchport mode trunk
然后在脚本里用 sed 做替换。这个做法的本质是把“配置策略”与“执行逻辑”分离。你要调整某条配置命令时,只需要改模板文件,所有设备都会跟着变。如果直接在 expect 脚本里写死命令,每次调整都要改脚本,维护成本就上来了。
对于不同厂商的设备,命令差异非常大。比如思科类设备用 switchport mode access,华为类设备用 port link-type access。遇到这种混牌环境,我建议在设备清单里再加一列“厂商型号标识”,然后在脚本里根据这个标识调用不同的配置模板。虽然比单一厂商环境多写几个模板,但效果是脚本仍然一套,只是模板文件多了几个。
3. 网络状态监控:让 Shell 脚本替你 7×24 值班
3.1 三层监控设计:连通性、设备健康、链路质量
网络状态监控是网络管理员另一个高频场景。最原始的做法是等用户报障,但这显然太被动。我通常把 Shell 监控分成三个层次,每一层关注的问题不同:
- 连通性监控:设备能不能 ping 通,丢包率是不是正常。这是最基础的探活,能快速发现设备宕机或链路中断。
- 设备健康监控:CPU 占用率、内存使用率、温度是否超阈值。这需要登录设备执行 show 命令,或者通过 SNMP 抓取。
- 链路质量监控:端口状态是否 up、有没有 CRC 错误、光模块光功率是否在正常范围。这层通常要读取接口计数器数据。
Shell 脚本在三个层级都有用武之地。第一层最常用,用 ping 命令就能实现;第二层和第三层需要结合 expect 或 SNMP 命令。下面我会重点讲连通性监控脚本的完整实现,然后说明设备健康监控和链路质量监控的实现思路。
3.2 一个可以直接落地的连通性监控脚本
我写监控脚本时有一个原则:脚本可以简单,但不能没有告警输出。否则监控脚本本身变成了一个只会写日志的“哑巴”,设备挂了还要人主动去翻日志,那还不如不监控。
下面是连通性监控脚本的核心逻辑:
bash复制#!/bin/bash
# 网络连通性监控脚本
# 每 5 分钟执行一次,检测设备丢包率和连通性
DEV_LIST="/opt/nettool/device.list"
LOG_DIR="/var/log/netmon"
LOSS_LOG="$LOG_DIR/loss.log"
DOWN_LOG="$LOG_DIR/down.log"
ALERT_WEBHOOK="https://example.com/webhook/alert"
# 确保日志目录存在
mkdir -p "$LOG_DIR"
grep -Ev '^\s*#|^\s*$' "$DEV_LIST" | while read ip name; do
# 每台设备发 10 个 ping 包,间隔 0.2 秒,超时 1 秒
ping_result=$(ping -c 10 -i 0.2 -W 1 "$ip" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "[$(date '+%F %T')] $name ($ip) 不可达" >> "$DOWN_LOG"
# 调用群机器人告警
curl -s -X POST "$ALERT_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"msg\": \"网络告警: $name ($ip) 不可达\"}" > /dev/null
continue
fi
# 从 ping 命令结果中提取丢包率
loss=$(echo "$ping_result" | awk -F'[=,]' '/packet loss/{print $2}' | tr -d ' ')
echo "[$(date '+%F %T')] $name ($ip) 丢包率: $loss" >> "$LOG_DIR/ping_$(date +%F).log"
if [ "$loss" != "0%" ]; then
echo "[$(date '+%F %T')] $name ($ip) 丢包异常: $loss" >> "$LOSS_LOG"
curl -s -X POST "$ALERT_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"msg\": \"链路告警: $name ($ip) 丢包 $loss\"}" > /dev/null
fi
done
这个脚本有几个执行细节需要单独说明。
首先是 ping 的参数。-c 10 表示发 10 个包,-i 0.2 表示包间隔 200 毫秒,-W 1 表示每个包的等待超时是 1 秒。这组参数配合下来,每台设备大约 2 秒内能完成一轮检测,不会因为一台设备无响应就拖住整个脚本。如果使用默认参数,ping 一个不可达的地址可能要等很久,批量场景下会严重影响效率。
其次是丢包率提取的可靠性。不同系统的 ping 输出格式有差异,Linux 下常见格式是 10 packets transmitted, 10 received, 0% packet loss。用 awk -F'[=,]' 把等号和逗号都作为分隔符,提取第二个字段就是丢包率。如果换到别的系统,这段解析逻辑可能需要微调。
再次是告警输出的防抖。生产环境最怕“告警风暴”,脚本每 5 分钟跑一次,如果设备持续不可达,半小时内就会收到 6 条相同告警。实际线上使用我建议加一个“连续失败 N 次才告警”的防抖判断,方法很简单:在日志目录里为每台设备维护一个失败计数的临时文件,连续失败次数达到阈值才触发告警,告警后清空计数。
3.3 把监控结果接入群机器人或短信
监控脚本的最终价值在于“及时感知异常”,而“及时感知”依赖告警通道。我在实际环境中用得最多的告警通道是钉钉或企业微信的群机器人 Webhook,因为配置简单、免费、手机端能收到推送。
上面的脚本已经演示了用 curl 推送 Webhook 的方式。除了直接推消息,还可以在消息里附带简单的 markdown 格式,把设备名、IP、丢包率、检测时间都展示出来。这个效果在手机上看非常直观,值班人员不用登录服务器就知道哪台设备出了问题。
如果内网没有外网条件,也可以改用邮件告警,用 mail -s 或者 sendmail 命令把告警内容发到运维组邮箱。更传统一点的做法是把异常追加到一个固定文件,配合 Zabbix 的自定义监控项去采集。总之 Shell 的优势是适配各种通道,脚本的主体逻辑不需要变,只要换掉最后的“通知”部分。
3.4 健康检查:CPU、内存与端口状态抓取
ping 只能证明设备“活着”,不能证明设备“健康”。一台设备 CPU 打满、温度报警、端口反复震荡,ping 都是通的,但业务已经受到影响了。所以在连通性监控之外,我还会用 expect 写一个巡检脚本,定期登录设备抓取关键状态。
抓取的命令因厂商而异,但思路统一:登录设备、执行 show 命令、保存输出、用 grep/awk 提取关键数值、和阈值比较。比如:
bash复制show cpu | include CPU
show memory | include Memory
show interfaces status | include connected
show environment | include Temperature
判断逻辑也很直接。比如 CPU 连续 5 分钟超过 80%,说明设备可能存在异常流量或者有环路;温度超过设备规格上限,则需要现场检查风扇和机房环境;接口状态频繁变化则可能是光模块衰减或线缆松动。这些阈值可以根据设备型号和使用场景灵活调整,在脚本里用变量定义即可。
3.5 定时任务与日志轮转不能忘
Shell 监控脚本写完,最后一步是配置 crontab 定时执行。我习惯把监控脚本放在 /opt/nettool/ 下,crontab 配置如下:
cron复制*/5 * * * * /opt/nettool/ping_monitor.sh > /dev/null 2>&1
0 */2 * * * /opt/nettool/device_health_check.sh > /dev/null 2>&1
这里需要特别提醒的是日志轮转。监控脚本每 5 分钟跑一次,每次写一行日志,一天下来日志文件就接近 300 行,如果时不时产生告警,日志增长会非常快。没有日志轮转机制,几个月后磁盘被日志打满的情况是很常见的。配置一个 logrotate 规则能避免这个坑:
text复制/var/log/netmon/*.log {
daily
rotate 30
compress
missingok
notifempty
}
保留 30 天的历史日志对于日常运维排障完全够用,既控制了磁盘占用,又保留了足够长的追溯窗口。
4. 踩坑实录:批量操作最容易翻车的四个场景
4.1 设备 SSH 会话数限制导致间歇性登录失败
批量脚本第一轮跑线上环境时,最容易遇到的问题就是设备 SSH 会话数限制。很多网络设备默认只允许 4 到 5 个并发 SSH 会话,如果脚本用并发方式同时登录多台设备,或者同一台设备脚本和人工同时登录,就很容易触发会话数上限,表现是一个连接建立成功,下一个连接直接被拒绝。
这个问题的排查链路值得记录。脚本跑了一半,日志里出现“Connection closed by remote host”,第一反应是密码错了,但手动 SSH 又能正常登录。仔细看日志才发现出错设备是集中且随机的,符合并发连接上限的特征。
解决方法是把并发改为串行,设备间加 sleep 间隔。同时检查设备配置,如果允许,把 SSH 会话数上限调大到 8 或 16,给自动化操作留出余量。运维过程中要记住一条:网络设备是资源受限的硬件设备,不像服务器能随便支撑几百个并发连接,自动化脚本要尊重设备的处理能力。
4.2 不同厂商不同版本命令不兼容
这是网络设备自动化特有的大坑。同样是配置一个 trunk 口,Cisco 系是 switchport trunk allowed vlan all,华为 VRP 系是 port link-type trunk 加 port trunk allow-pass vlan all,H3C Comware 系又是另一套写法。如果设备清单里没有厂商标识,脚本拿 Cisco 的命令去配华为设备,轻则命令被拒,重则策略配错。
我早期吃过一次亏,那时环境里主力是某品牌设备,后来新进了一批另一品牌的交换机,我没注意台账更新,脚本直接跑上去,结果新设备上所有接口都处于异常状态。从那以后我强制规定:设备清单必须包含厂商和型号字段,入口脚本根据这个字段选择对应的配置模板,宁可多写几个模板,也不能用一套命令通吃。
4.3 配置中途断线导致设备处于半配置状态
这是批量自动化里事故等级最高的一个场景。设备已经执行了 configure terminal 进入全局配置模式,VLAN 建到一半、接口命令执行到第三条,SSH 突然断开。这个时候设备可能处于配置半应用状态,需要人工介入才能恢复。
降低这个风险,我有三层做法:
- 配置前先自动备份现有配置到本地,脚本登录设备后第一件事是执行
show running-config或类似命令,把结果保存下来。 - 把配置拆分成多个独立阶段,每阶段都做一次完整校验,而不是靠一条长命令跑完全部。
- 在最重要的配置下发之前,确认设备管理接口的配置语句已经提前完成,避免中途断网。
4.4 “先干再说”没有回滚预案,出问题只能现场救火
批量配置最忌讳的就是变更前不准备回滚方案。我有一次在办公楼宇接入交换机上批量调整 VLAN,脚本是按标准模板跑的,但有一台设备上联口配置和模板不一致,脚本执行后那台设备直接断联,整层办公室网络瘫痪。由于没有提前准备回滚脚本,只能抱着笔记本跑现场,通过 console 口恢复,前后折腾了四十分钟。
在这个项目之后,我给自己定了一条规矩:凡是生产环境批量变更,必须先出回滚预案。具体落地就是在变更前用脚本把所有设备的当前关键配置导出一份,一旦变更后出现异常,可以用一条恢复脚本把设备配置还原到变更前状态。另外,批量配置不能一口气跑完所有设备。我的实践经验是分三批:先跑 1 台设备并验证,再跑 10% 的设备,确认稳定后再跑剩余全部。这个灰度策略看着保守,但能挡住大部分灾难性变更。
5. 进阶:把零散脚本整理成一整套可维护的运维小工具
5.1 合适的目录结构与公共函数库
脚本数量一多,放在一起乱成一锅粥是必然的。我最终形成的目录结构大概是这样:
text复制/opt/nettool/
├── bin/ # 可执行脚本
│ ├── deploy.exp
│ ├── batch_deploy.sh
│ ├── ping_monitor.sh
│ └── device_health_check.sh
├── conf/ # 配置文件与设备清单
│ ├── device.list
│ └── alert.conf
├── templates/ # 配置模板
│ ├── cisco_switch.tpl
│ ├── huawei_switch.tpl
│ └── h3c_switch.tpl
├── logs/ # 执行日志
└── backup/ # 设备配置备份
这个目录结构看着简单,但维护价值很高。设备清单和模板放在 conf 和 templates 目录,脚本放在 bin 目录,日志和备份独立存放。这样在排查问题时能快速定位每一类文件的存放位置。
把公共操作抽成函数库也是一个好习惯。比如“发告警”和“写日志”这两个操作在多个脚本里都要用,单独抽出来放到 common.sh 里,其他脚本 source 一下就能调用。这样修改告警通道时只需要改一个文件,所有脚本统一生效。常见公共函数包括:
bash复制log() {
echo "[$(date '+%F %T')] $*" >> "$LOG_FILE"
}
send_alert() {
local msg="$1"
curl -s -X POST "$ALERT_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"msg\": \"$msg\"}" > /dev/null
}
backup_config() {
local ip="$1"
local name="$2"
local ts=$(date +%Y%m%d%H%M%S)
expect /opt/nettool/bin/backup.exp "$ip" "$name" > "/opt/nettool/backup/${name}_${ts}.cfg"
}
5.2 凭据管理与安全注意事项
Shell 脚本最大的安全隐患就是密码硬编码。我曾经见过同事把设备密码直接写在脚本里,结果脚本文件被复制来复制去,密码也跟着传了个遍。这类安全问题一旦发生,影响范围很难控制。
常见的改善方案是使用环境变量或独立的凭据配置文件,并把文件的权限设置为 600,只有执行脚本的管理员可读。更稳妥的方式是使用 SSH key 认证而不是密码认证,但部分老旧网络设备对 SSH key 的支持有限,落地时需要先评估设备能力。对于生产环境,我建议至少做到:
- 脚本文件不包含明文密码。
- 设备密码集中存放于权限受控的文件中,脚本启动时加载。
- 定期轮换设备密码,随密码变更及时更新凭据文件。
- 自动化账号使用最小权限,只授予执行配置变更所需的命令权限。
5.3 什么情况下该换更专业的自动化工具
Shell 脚本在网络运维自动化里非常重要,但它不是万能的。随着设备规模增长,Shell 脚本的局限性会越来越明显:没有配置漂移检测、没有直观的执行报告、对并发和失败重试的支持需要自己造轮子。
我个人认为,当监控设备数量超过 200 台,或者需要频繁做合规审计和配置一致性检查时,就该考虑引入 Ansible 或 Nornir 这类专业工具。Ansible 的 network_cli 连接方式可以复用现有的 SSH 协议,但提供了幂等性、playbook 编排和结构化输出;Nornir 基于 Python,适合需要复杂逻辑判断的场景。但这不代表 Shell 脚本要废弃。更合理的思路是:Shell 脚本负责快速部署、临时排障和轻量巡检;专业自动化平台负责规模化变更和合规管理。两者配合,才能覆盖网络运维的不同场景。
5.4 把脚本版本管理起来
最后一条进阶建议是给脚本做版本管理。我自己用本地的 git 仓库来管理 /opt/nettool/ 下所有脚本和模板。每次修改脚本前先提交当前版本,改完后再提交一次,保证任何时候都能回退到上一个可用版本。这个习惯在最开始看起来有点繁琐,但实际操作中发现它不仅保证了自己的脚本可追溯,也方便和同事协作修改脚本。如果哪天你手误删了一个好用的函数,git 能让你几分钟内恢复现场,而不是凭记忆重写一遍。
网络设备自动化这块,我的体会是“别贪大求全,从小脚本开始”。先把手头最痛的一两个场景用 Shell 脚本自动化掉,跑顺了再逐步扩大范围。脚本不是一次性写就万事大吉的,设备型号在换、业务需求在变,脚本也需要定期维护更新。每次新脚本上线,先单台试跑,确认输出符合预期后再小批量灰度,最后才全量执行,这套节奏虽然慢一点,但稳,尤其是面对生产网络的时候,稳妥比炫技重要得多。
