使用Paramiko备份网络交换机仅获设备名称,无法获取完整配置
解决Paramiko执行交换机
show running-config仅返回提示符的问题 常见原因及修复方案
1. 关闭交换机命令输出分页
多数交换机默认启用分页(显示--More--),exec_command一次性发送命令后,可能因分页机制卡住,仅返回提示符或第一页内容。需先执行terminal length 0关闭分页,再获取配置:
stdin, stdout, stderr = ssh.exec_command('terminal length 0\nshow running-config')
2. 改用交互式Shell会话
部分网络设备对exec_command的非交互式执行支持不佳,需通过invoke_shell建立交互式会话,模拟手动操作流程:
# 替换原exec_command相关代码 shell = ssh.invoke_shell() # 关闭分页 shell.send('terminal length 0\n') time.sleep(1) # 等待设备响应 # 发送配置查询命令 shell.send('show running-config\n') time.sleep(3) # 根据设备配置大小调整等待时长 # 读取完整输出并解码 output = shell.recv(65535).decode('utf-8') # 清理冗余内容(命令行、空行、提示符) output = output.replace('terminal length 0', '').replace('show running-config', '').strip()
注意需提前导入time模块:import time
3. 优化输出读取方式
原代码用stdout.readlines()可能因输出未完全返回导致截断,改用stdout.read()获取完整字节流后解码:
stdin, stdout, stderr = ssh.exec_command('terminal length 0\nshow running-config') stdin.close() # 读取完整输出并解码 output = stdout.read().decode('utf-8') # 过滤冗余行 clean_lines = [line for line in output.split('\n') if not line.startswith(('terminal length 0', 'show running-config')) and line.strip()] output = '\n'.join(clean_lines)
4. 修正错误输出处理逻辑
原代码中两次读取stderr会导致第二次读取为空,应合并处理:
errors = stderr.read().decode('utf-8') if errors: print(f"{IP}执行出错: {errors}")
完整修复后的示例代码
import pandas import paramiko import time # Connection info USERNAME = "username" PW = "password" PORT = 22 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Backup \ import location DEST = "C:\\temp\\test\\" CSV = DEST+"Switches.csv" device_list = pandas.read_csv(CSV) for index, row in device_list.iterrows(): IP = row["IP"] floor = row["Floor"] side = row["Side"] formatted_ip = IP.replace(".", "_") filename = f"{formatted_ip}_{floor}{side}.txt" try: ssh.connect(hostname=IP, username=USERNAME, password=PW, port=PORT, timeout=10) # 建立交互式Shell shell = ssh.invoke_shell() # 关闭分页 shell.send('terminal length 0\n') time.sleep(1) # 发送配置查询命令 shell.send('show running-config\n') time.sleep(3) # 读取并清理输出 raw_output = shell.recv(65535).decode('utf-8') clean_output = [] for line in raw_output.split('\n'): stripped_line = line.strip() if stripped_line not in ['terminal length 0', 'show running-config', ''] and not stripped_line.endswith(('>', '#')): clean_output.append(line) final_output = '\n'.join(clean_output) # 写入备份文件 with open(DEST + filename, "w") as outfile: outfile.write(final_output) print(f"{IP} 备份完成") except Exception as e: print(f"{IP} 备份失败: {str(e)}") finally: # 确保SSH连接关闭 if ssh.get_transport() and ssh.get_transport().is_active(): ssh.close()
额外注意事项
- 调整
time.sleep()时长:若交换机配置较大,需延长等待时间避免输出截断 - 编码适配:部分设备可能使用
gbk等编码,解码时可尝试decode('gbk') - 特权模式适配:若设备需进入特权模式,需先发送
enable命令及特权密码,再执行配置查询
内容的提问来源于stack exchange,提问作者titors
相关产品推荐
相关产品推荐

