You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:09:25