【问题标题】:subprocess.CalledProcessError and ssh connection drops when an ssh command to a Cisco router produces large output当对 Cisco 路由器的 ssh 命令产生大量输出时,subprocess.CalledProcessError 和 ssh 连接断开
【发布时间】:2017-10-26 22:39:00
【问题描述】:

我的代码有问题。输出小时效果很好,输出大时就坏了。

这是我的代码:

def listDevices(username, pass, regex):
    command = "list-dev " + regex
    deviceArray = []
    connectString = "plink -ssh -l " + username + " -pw " + pass + " -P " + SshPort + " " + Server + " \"" + command + "\""
    rawList = subprocess.check_output(connectString, shell=True)
          for line in rawList.split("\r\n"):
              if "" is not line:
                  deviceArray.append(line)
          print deviceArray
          return deviceArray

Server = 10.10.10.1
SshPort = 22 
username = "test"
pass - "password"  
regex = "rt*mdr*"    

mdrList = listDevices(username, pass, regex)
print mdrList

这在数据较小时可以正常工作,但在数据较大时会失败。

这是错误:

subprocess.CalledProcessError: Command 'plink -ssh -l test -pw password -P 4000 10.10.10.1 "list-dev *"' returned non-zero exit status 1

编辑:

我替换了 plink 并写了 paramiko,但仍然没有得到所有数据。这是代码:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ip,username=username, password=password, port = 9000)
list =["list-devices rt*"]
command = '\n'.join(list)
print command
stdin,stdout,stderr = ssh.exec_command(command)
print stdout.read()

它给了我以下错误:

Traceback (most recent call last):
  File "C:/Users/xx/Scripts/Test2.py", line 31, in <module>
    stdin,stdout,stderr = ssh.exec_command(command)
  File "C:\Python27\paramiko\client.py", line 404, in exec_command
    chan.exec_command(command)
  File "C:\Python27\paramiko\channel.py", line 60, in _check
    return func(self, *args, **kwds)
  File "C:\Python27\paramiko\channel.py", line 229, in exec_command
    self._wait_for_event()
  File "C:\Python27\paramiko\channel.py", line 1086, in _wait_for_event
    raise e
paramiko.ssh_exception.SSHException: Channel closed.

【问题讨论】:

  • 您可以使用subprocess.check_output() 来简化一下吗?您不需要写入临时文件。
  • @Wyatt,这正是我已经在第一个做的,但它失败了。我创建了第二个,认为保存到文件可能会起作用,但它也没有。它适用于小数据,但当数据很大时,它就会失败。
  • 我浏览了第一个版本,实际上只看了第二个版本。看起来plink 命令在更大的数据上超时。如果直接在命令行运行,是否成功完成?
  • @Wyatt,你是对的。我在电源外壳上运行了命令,几秒钟后我收到了服务器发送断开连接请求的致命错误。是plink限制还是服务器是这样设置的?如果是 plink,你知道有什么替代 plink 的方法吗?
  • 顺便说一句,subprocess.check_output(connectString, shell=True) 从安全角度来看是完全危险的。如果用户提供的密码包含 ; rm -rf ~ 或任何平台本地 Windows 等效项怎么办?传递显式参数列表比传递字符串更安全。

标签: python python-2.7 subprocess cisco


【解决方案1】:

根据plink ssh not working with multiple commands passed in a file. - 65059 - The Cisco Learning Network,这是 Cisco 路由器的问题,因此与 Python 无关。

  • SSH using public key authentication to ... - Cisco Support Community 表示,只要 Cisco 在输入上看到 EOF,它就会断开连接的双方,即使根据 TCP 规则,它应该只关闭输入套接字。它建议的解决方法是延迟 EOF,直到下载所有输出。它使用了一个又快又脏的sleep,但这对于脚本来说是不可靠的。

  • Putty Dies with Large Output : networking - Reddit 说这是 MTU 问题。症状是无法获得超过一屏的信息:

    我遇到了一些在终端中表现出来的与 MTU 相关的问题 模拟器以类似的方式。通常是某种 在 VLAN 中承载的点对点专线 用于标记混乱并在传输过程中丢弃帧的字节。什么时候 发生这种情况,较短的输出会很好,但较长的输出 只会杀死会话。有时优雅,有时不优雅。

事实上,最后一个似乎是正确的解释。触发连接断开的不是EOF,而是恰好包含它的命令之后的附加数据。第一个链接的另一种解决方法是在输入命令之间插入几个换行符——这样看,它们用作填充,而不是损坏的传输逻辑会插入并阻塞它的填充。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    • 2016-08-26
    • 2011-07-11
    • 2021-07-16
    • 1970-01-01
    相关资源
    最近更新 更多