2011-03-17 13 views
7

Bir uygulama ile ilgili sorun yaşıyorum, bu yazıyı yüklerim ve dosyaları SSH üzerinden diğer kutulara yükler. Yaşıyorum sorun şu ki (download) dosyaları sadece iyi olabilir ama ben onları başka bir sunucuya koymaya çalıştığımda bir EOFError() istisnası alıyorum. Paramiko \ sftp.py dosyasındaki _write_all() 'a baktığımda, akışa herhangi bir veri yazamadığında hata oluşmuş gibi görünüyordu. Ağ programlama deneyimim yok, eğer birisi ne yapmaya çalıştığını biliyorsa ve bunu bana iletebilseydi bunu takdir ediyorum.Neden Paramiko, SFTP nesnesi bir sözlükte saklandığında EOFError() öğesini yükseltiyor?

Bağlantılarımı ssh() olarak işleyen işlevin basitleştirilmiş bir sürümünü yazdım. runCommand(), uygulamamda yüklemenin nasıl başarısız olduğunu gösterirken, simpleTest() sftp komutunun çalışma şeklini gösterir, ancak SFTP nesnelerimin nasıl depolandığından başka runCommand() ve simpleTest() arasında hiçbir fark göremiyorum. Bir sözlükte ve diğeri kendi içinde saklanır. Söz konusu dosyalar, indirme dosyalarının çalışmadığı sorun değil gibi görünüyor, ancak durum böyle değil.

Bu davranışa neyin neden olabileceğini bilen var mı, yoksa bu şekilde sorunlara neden oluyorsa bağlantılarımı yönetmenin başka bir yolunu önerebilir mi?

Paramiko 1.7.6 ile Python 2.7 kullanıyorum. Bu kodu hem Linux hem de Windows üzerinde test ettim ve aynı sonuçları aldım.

DÜZENLEME: kod şimdi dahil.

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() 

çıkışı:

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 

cevap

6

Sorunumu çözebiliyordum. Paramiko.Transport kullanıyordum ve SSHClient()'dan open_sftp() yerine paramiko.SFTPClient.from_transport(t) ile SFTPClient oluşturuyordum.

Aşağıdaki kod çalışır: i bir SSHClient-Nesnesi oluşturmak ve sonra sftp = ssh.open_sftp() ile bir sftp-nesne oluşturmak) ssh = SSHClient (ile onu

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

, aynı kodu kullanın, bu istisna rastgele kaldırılır – Shaw

0

Düzenlemenizi okuduktan sonra ben sorunu bu hat görünüşte EDITED ftp şey

kesmek burada

stdin, stdout, stderr = self.sshConnections[host].exec_command(command) 

olduğunu düşünüyorum

+0

Yorum, aşağıya doğru hareket etmek için taşındı. Ancak, – Vye

2

gördüğünüz gibi . sadece sftp'yi kullanmak istediğinizde, ssh'i yerel bir değişkene saklarsınız, bu da gc'd olur, ancak, ssh gc'd ise, sftp sihirli bir şekilde çalışmayı durdurur. nedenini bilmiyorum, ama ssh'ı yaşadığın zaman için saklamayı dene.

İlgili konular