2011-03-17 5 views
7

मुझे एक ऐसे एप्लिकेशन के साथ परेशानी हो रही है जिसे मैं लिख रहा हूं और एसएसएच के माध्यम से अन्य बक्से से फ़ाइलें अपलोड और अपलोड करता हूं। जिस समस्या का मैं अनुभव कर रहा हूं वह यह है कि मैं फ़ाइलों को ठीक (डाउनलोड) कर सकता हूं लेकिन जब मैं उन्हें किसी अन्य सर्वर पर डाल (अपलोड) करने का प्रयास करता हूं तो मुझे एक EOFError() अपवाद मिलता है। जब मैंने paramiko \ sftp.py में _write_all() को देखा तो ऐसा लगता था कि त्रुटि तब हुई जब यह धारा में कोई डेटा नहीं लिख सका? मेरे पास कोई नेटवर्क प्रोग्रामिंग अनुभव नहीं है, इसलिए यदि कोई जानता है कि वह क्या करने की कोशिश कर रहा है और मुझसे संवाद कर सकता है तो मैं इसकी सराहना करता हूं।पैरामीको EOFError() को क्यों बढ़ा रहा है जब एसएफटीपी ऑब्जेक्ट को एक शब्दकोश में संग्रहीत किया जाता है?

मैंने फ़ंक्शन का सरलीकृत संस्करण लिखा है जो मेरे कनेक्शन को ssh() के रूप में संभालता है। runCommand() दिखाता है कि मेरे एप्लिकेशन में अपलोड कैसे विफल हो रहा है जबकि सरलटेस्ट() दिखाता है कि कैसे sftp डालता काम करता है, लेकिन मैं अपने एसएफटीपी ऑब्जेक्ट्स को संग्रहीत करने के अलावा रनकॉमंड() और सरलटेस्ट() के बीच कोई अंतर नहीं देख सकता। एक को एक शब्दकोश में और दूसरे में ही संग्रहीत किया जाता है। ऐसा लगता है जैसे शब्दकोश था कि फाइलें डाउनलोड करने वाली समस्या काम नहीं करेगी, लेकिन ऐसा नहीं है।

क्या किसी को पता है कि इस व्यवहार का कारण क्या हो सकता है या यदि इस तरह से समस्याएं पैदा हो रही हैं तो मेरे कनेक्शन को प्रबंधित करने के लिए एक और तरीका सुझा सकता है?

मैं पैरामीको 1.7.6 के साथ पायथन 2.7 का उपयोग कर रहा हूं। मैंने इस कोड का परीक्षण लिनक्स और विंडोज दोनों पर किया है और उसी परिणाम प्राप्त हुए हैं।

संपादित करें: कोड अब शामिल है।

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 

उत्तर

6

मैं अपनी समस्या का समाधान करने में सक्षम था। मुझे पैरामीको का उपयोग करना था। ट्रांसपोर्ट और फिर से open_sftp() का उपयोग करने के बजाय paramiko.SFTPClient.from_transport(t) के साथ SFTPClient बनाना।

निम्नलिखित कोड काम करता है:

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

हालांकि, एक ही कोड का उपयोग करें, यह अपवाद यादृच्छिक रूप से उठाया गया है – Shaw

0

अपने संपादित पढ़ने के बाद मुझे लगता है कि समस्या यहाँ

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

है इस लाइन जाहिरा तौर पर एफ़टीपी बात

संपादित डिस्कनेक्ट

012,
+0

टिप्पणी नीचे उत्तर देने के लिए स्थानांतरित हो गया। – Vye

2

के रूप में मैं इसे) को देखने के आप एक SSHClient-वस्तु बनाते हैं और फिर SFTP = ssh.open_sftp() के साथ एक SFTP-वस्तु बनाने के साथ ssh = SSHClient (, । जबकि आप केवल sftp का उपयोग करना चाहते हैं, तो आप ssh को स्थानीय चर में संग्रहीत करते हैं, जो तब gc'd हो जाता है, लेकिन, अगर ssh gc'd है, तो sftp जादुई रूप से काम करना बंद कर देता है। पता नहीं क्यों, लेकिन अपने sftp जीवन के लिए एसएसएच स्टोर करने की कोशिश करें।

संबंधित मुद्दे