当 SFTP 对象存储在字典中时,为什么 Paramiko 会引发 EOFError()? [英] Why is Paramiko raising EOFError() when the SFTP object is stored in a dictionary?

查看:59
本文介绍了当 SFTP 对象存储在字典中时,为什么 Paramiko 会引发 EOFError()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写的一个应用程序遇到问题,该应用程序通过 SSH 将文件下载到其他设备或从其他设备上载文件.我遇到的问题是我可以很好地获取(下载)文件,但是当我尝试将(上传)它们到另一台服务器时,我得到一个 EOFError() 异常.当我查看 paramiko\sftp.py 中的 _write_all() 时,似乎错误是由于无法将任何数据写入流而引起的?我没有网络编程经验,所以如果有人知道它要做什么并且可以与我交流,我将不胜感激.

I'm having trouble with an application I'm writing that downloads and uploads files to and from other boxes via SSH. The issue I'm experiencing is that I can get (download) files just fine but when I try to put (upload) them onto another server I get an EOFError() exception. When I looked at _write_all() in paramiko\sftp.py it seemed like the error was caused when it couldn't write any data to the stream? I have no network programming experience so if someone knows what it's trying to do and could communicate that to me I'd appreciate it.

我编写了一个简化版本的函数,将我的连接处理为 ssh().runCommand() 显示了在我的应用程序中上传是如何失败的,而 simpleTest() 显示了 sftp put 是如何工作的,但是除了我的 SFTP 对象的存储方式之外,我看不出 runCommand() 和 simpleTest() 之间有任何区别.一个存储在字典中,另一个单独存储.似乎字典是下载文件不起作用的问题,但事实并非如此.

I wrote a simplified version of the function that handles my connections as ssh(). runCommand() shows how the upload is failing in my application while simpleTest() shows how sftp put does work, but I can't see any difference between runCommand() and simpleTest() other than how my SFTP objects are being stored. One is stored in a dictionary and the other by itself. It seems like if the dictionary was the problem that downloading files wouldn't work but that is not the case.

有人知道是什么导致了这种行为,或者如果这种方式导致问题,可以推荐另一种方式来管理我的连接吗?

Does anyone know what could cause this behavior or could recommend another way to manage my connections if this way is causing problems?

我使用 Python 2.7 和 Paramiko 1.7.6.我已经在 Linux 和 Windows 上测试了这段代码并得到了相同的结果.

I'm using Python 2.7 with Paramiko 1.7.6. I've tested this code on both Linux and Windows and got the same results.

现在包含代码.

import os
import paramiko

class ManageSSH:
     """Manages ssh connections."""
    def __init__(self):
        self.hosts = {"testbox": ['testbox', 'test', 'test']}
        self.sshConnections = {}
        self.sftpConnections = {}
        self.localfile = "C:\\testfile"
        self.remotefile = "/tmp/tempfile"
        self.fetchedfile = "C:\\tempdl"

    def ssh(self):
        """Manages ssh connections."""
        for host in self.hosts.keys():
            try:
                self.sshConnections[host]
                print "ssh connection is already open for %s" % host
            except KeyError, e:         # if no ssh connection for the host exists then open one
                # open ssh connection
                ssh = paramiko.SSHClient()
                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                ssh.connect(self.hosts[host][0], 22, self.hosts[host][1], self.hosts[host][2])
                self.sshConnections[host] = ssh
                print "ssh connection to %s opened" % host
            try:
                self.sftpConnections[host]
                print "sftp connection is already open for %s" % host
            except KeyError, e:
                # open sftp connection
                ssh = paramiko.SSHClient()
                ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                ssh.connect(self.hosts[host][0], 22, self.hosts[host][1], self.hosts[host][2])
                self.sftpConnections[host] = ssh.open_sftp()
                print "sftp connection to %s opened" % host

    def runCommand(self):
        """run commands and return output"""
        for host in self.hosts:
            command = "if [ -d /tmp ]; then echo -n 1; else echo -n 0; fi"
            stdin, stdout, stderr = self.sshConnections[host].exec_command(command)
            print "%s executed on %s" % (command, host)
            print "returned %s" % stdout.read()
            self.sftpConnections.get(self.remotefile, self.fetchedfile)
            print "downloaded %s from %s" % (self.remotefile, host)
            self.sftpConnections[host].put(self.localfile, self.remotefile)
            print "uploaded %s to %s" % (self.localfile, host)
            self.sftpConnections[host].close()
            self.sshConnections[host].close()

    def simpleTest(self):
        host = "testbox"
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(host, 22, 'test', 'test')
        sftp = ssh.open_sftp()
        print "sftp connection to %s opened" % host
        sftp.get(self.remotefile, self.fetchedfile)
        print "downloaded %s from %s" % (self.localfile, host)
        sftp.put(self.localfile, self.remotefile)
        print "uploaded %s to %s" % (self.localfile, host)
        sftp.close()

if __name__ == "__main__":
    test = ManageSSH()
    print "running test that works"
    test.simpleTest()
    print "running test that fails"
    test.ssh()
    test.runCommand()

输出:

running test that works
sftp connection to testbox opened
downloaded C:\testfile from testbox
uploaded C:\testfile to testbox
running test that fails
ssh connection to testbox opened
sftp connection to testbox opened
if [ -d /tmp ]; then echo -n 1; else echo -n 0; fi executed on testbox
returned 1
downloaded /tmp/tempfile from testbox
Traceback (most recent call last):
  File "paramikotest.py", line 71, in <module>
    test.runCommand()
  File "paramikotest.py", line 47, in runCommand
    self.sftpConnections[host].put(self.localfile, self.remotefile)
  File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 561, in put

    fr = self.file(remotepath, 'wb')
  File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 245, in open
    t, msg = self._request(CMD_OPEN, filename, imode, attrblock)
  File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 627, in _request
    num = self._async_request(type(None), t, *arg)
  File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 649, in _async_request
    self._send_packet(t, str(msg))
  File "C:\Python27\lib\site-packages\paramiko\sftp.py", line 172, in _send_packet
    self._write_all(out)
  File "C:\Python27\lib\site-packages\paramiko\sftp.py", line 138, in _write_all

    raise EOFError()
EOFError

推荐答案

我能够解决我的问题.我应该使用 Paramiko.Transport,然后使用 paramiko.SFTPClient.from_transport(t) 而不是使用 open_sftp() 创建 SFTPClient来自 SSHClient().

I was able to resolve my issue. I was supposed to be using Paramiko.Transport and then creating the SFTPClient with paramiko.SFTPClient.from_transport(t) instead of using open_sftp() from SSHClient().

以下代码有效:

t = paramiko.Transport((host, 22))  
t.connect(username=username, password=password)  
sftp = paramiko.SFTPClient.from_transport(t)

这篇关于当 SFTP 对象存储在字典中时,为什么 Paramiko 会引发 EOFError()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆