Python编写的Cisco交换机出厂重置脚本Break功能失效问题
Cisco交换机串口自动化重置脚本故障排查与修复
问题概述
批量重置旧Cisco交换机时,编写的Python脚本未能通过串口发送Break信号触发ROMmon模式。脚本控制台显示已检测到“Initializing Flash”提示并发送了命令,但交换机仍正常启动,未进入恢复模式。环境为Windows 10 + Python 3.10,原脚本代码如下:
import serial import time # Serial port configuration ser = serial.Serial("/dev/ttyUSB0", timeout=1) print(f"Connecting to {ser.name}...") # Strings for prompt detection initPrompt = "Initializing Flash" swPrompt = "switch:" ynPrompt = " (y/n)?" # Function to wait for specific prompt and send command def wait_for_prompt_and_send(prompt, command): while True: response = ser.read_until(prompt.encode("utf-8")).decode("utf-8") if prompt in response: print(f"Found prompt: {prompt}") ser.write(command) ser.write(b"\n") break # Connect and send initial break commands ser.write(b"\r") print("Sent carriage return...") time.sleep(0.5) wait_for_prompt_and_send(initPrompt, b"\x03") # break command # Initialize flash wait_for_prompt_and_send(swPrompt, b"flash_init\n\n") # Delete vlan.dat wait_for_prompt_and_send(swPrompt, b"del flash:vlan.dat\n") wait_for_prompt_and_send(ynPrompt, b"y\n") # Delete config.text wait_for_prompt_and_send(swPrompt, b"del flash:config.text\n") wait_for_prompt_and_send(ynPrompt, b"y\n") ser.close()
故障原因分析
- Windows串口路径错误:原脚本使用Linux风格的
/dev/ttyUSB0,Windows系统下串口应为COMx格式(如COM3),需通过设备管理器确认实际端口号。 - Break信号发送方式错误:
\x03是Ctrl+C,并非Cisco交换机识别的Break信号。Cisco的Break是串口硬件信号,需使用serial.send_break()方法发送。 - 串口参数不完整:原脚本未指定波特率、数据位等关键参数,Cisco交换机默认串口配置为
9600波特率、8数据位、1停止位、无奇偶校验。 - 发送时机滞后:交换机检测Break信号的窗口极短,等“Initializing Flash”提示出现后再发送,已错过触发时机,需在启动阶段提前循环发送Break。
修复后的脚本代码
import serial import time # Windows串口配置,替换为你的实际COM口 SERIAL_PORT = "COM3" BAUD_RATE = 9600 # 初始化串口,添加完整参数 ser = serial.Serial( port=SERIAL_PORT, baudrate=BAUD_RATE, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1 ) print(f"连接到串口 {ser.name}...") # 提示字符串定义 swPrompt = "switch:" ynPrompt = " (y/n)?" def wait_for_prompt(prompt): """等待指定提示出现,返回读取到的内容""" buffer = "" while True: chunk = ser.read(1024).decode("utf-8", errors="ignore") buffer += chunk if prompt in buffer: print(f"检测到提示: {prompt}") return buffer def send_command(cmd): """发送命令并换行""" ser.write(cmd.encode("utf-8")) ser.write(b"\r\n") time.sleep(0.5) # 触发Break信号:交换机上电后立即循环发送,直到进入ROMmon print("等待交换机启动,发送Break信号...") while True: # 发送Break信号(持续0.5秒) ser.send_break(duration=0.5) time.sleep(0.5) # 检查是否进入ROMmon buffer = ser.read(1024).decode("utf-8", errors="ignore") if swPrompt in buffer: print("已进入ROMmon模式") break # 初始化Flash wait_for_prompt(swPrompt) send_command("flash_init") # 删除vlan.dat wait_for_prompt(swPrompt) send_command("del flash:vlan.dat") wait_for_prompt(ynPrompt) send_command("y") # 删除config.text wait_for_prompt(swPrompt) send_command("del flash:config.text") wait_for_prompt(ynPrompt) send_command("y") # 重启交换机(可选) wait_for_prompt(swPrompt) send_command("boot") ser.close() print("脚本执行完成,串口已关闭")
使用说明
- 打开设备管理器,找到“端口(COM和LPT)”下的USB转串口设备,确认实际COM口编号,替换脚本中的
SERIAL_PORT。 - 确保交换机处于未上电状态,运行脚本后立即给交换机上电,脚本会自动循环发送Break信号直到进入ROMmon。
- 若仍无法触发,可调整
send_break()的duration参数(如改为1.0),或增加循环发送的频率。
内容的提问来源于stack exchange,提问作者Sebastian Buergi
相关产品推荐
相关产品推荐

