Paramiko .recv无法完整读取.send执行命令的输出
解决Paramiko invoke_shell发送命令后无法获取完整输出的问题
你遇到的核心问题是:用Paramiko的invoke_shell()创建交互式shell后,发送命令立刻调用recv(),此时设备还没完成命令处理并返回完整输出,只能读取到当前已返回的少量内容(比如提示符、命令开头字符)。
解决方案1:添加固定延迟(简单易上手)
设备执行命令需要时间,发送命令后先等几秒,让设备把输出准备好再读取。
补全缺失的导入并修改核心逻辑:
import paramiko from datetime import date import time # 新增导入时间模块 myfile = open('c:\znet\device-list.txt','r') count = 0 while True: count = count + 1 line = myfile.readline() if not line:break else: x = line.strip() y,z =x.split(",",1) print ("switch ",y) print ("IP address ",z) backupdate = str(date.today()) filename = y + "_" + backupdate print (filename) host = z user = 'cisco' password = 'cisco' client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy) client.connect(hostname=host, username=user, password=password) print ("Successfully log in to", y) remote = client.invoke_shell() # 先关闭命令行分页(避免设备返回部分内容后暂停) remote.send("terminal length 0\n") time.sleep(1) remote.recv(1048576) # 读取关闭分页的输出,不干扰后续命令 # 发送目标命令并等待设备响应 remote.send("show run int vlan 1\n") time.sleep(2) # 等待时间可根据设备响应速度调整(1-3秒) output = remote.recv(1048576) print (output.decode('ascii')) with open("{}.txt".format(filename),"w") as f: print (output.decode('ascii'),file=f)
解决方案2:循环读取直到检测到提示符(更可靠)
固定延迟可能不适合所有设备,你可以循环读取输出,直到捕获到交换机的提示符(比如#),确认命令执行完毕:
import paramiko from datetime import date import time myfile = open('c:\znet\device-list.txt','r') count = 0 while True: count = count + 1 line = myfile.readline() if not line:break else: x = line.strip() y,z =x.split(",",1) print ("switch ",y) print ("IP address ",z) backupdate = str(date.today()) filename = y + "_" + backupdate print (filename) host = z user = 'cisco' password = 'cisco' client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy) client.connect(hostname=host, username=user, password=password) print ("Successfully log in to", y) remote = client.invoke_shell() # 关闭分页 remote.send("terminal length 0\n") time.sleep(1) remote.recv(1048576) # 发送命令并循环读取输出 remote.send("show run int vlan 1\n") output = b"" while True: if remote.recv_ready(): output += remote.recv(1048576) # 检查是否出现交换机提示符(可根据设备实际情况调整) if b"#" in output: break time.sleep(0.5) # 每次等待0.5秒再检查 print (output.decode('ascii')) with open("{}.txt".format(filename),"w") as f: print (output.decode('ascii'),file=f)
关键注意点
- 必须关闭命令行分页:如果交换机默认用
--More--分页,不关闭的话只能拿到第一页内容,terminal length 0命令可以让设备一次性输出所有内容。 - 等待时间要合理:不同设备响应速度不同,延迟时间可以根据实际情况调整。
内容的提问来源于stack exchange,提问作者PF K
相关产品推荐
相关产品推荐

