2015-07-16 5 views
5

Wie kann ich os.walk den Verzeichnisbaum einer FTP-Datenbank (auf einem Remote-Server) durchlaufen? Die Art und Weise der Code strukturiert ist jetzt (Kommentare zur Verfügung gestellt):Erweiterung von Pythons os.walk-Funktion auf FTP-Server

import fnmatch, os, ftplib 

def find(pattern, startdir=os.curdir): #find function taking variables for both desired file and the starting directory 
    for (thisDir, subsHere, filesHere) in os.walk(startdir): #each of the variables change as the directory tree is walked 
     for name in subsHere + filesHere: #going through all of the files and subdirectories 
      if fnmatch.fnmatch(name, pattern): #if the name of one of the files or subs is the same as the inputted name 
       fullpath = os.path.join(thisDir, name) #fullpath equals the concatenation of the directory and the name 
       yield fullpath #return fullpath but anew each time 

def findlist(pattern, startdir = os.curdir, dosort=False): 
    matches = list(find(pattern, startdir)) #find with arguments pattern and startdir put into a list data structure 
    if dosort: matches.sort() #isn't dosort automatically False? Is this statement any different from the same thing but with a line in between 
    return matches 

#def ftp(
#specifying where to search. 

if __name__ == '__main__': 
    import sys 
    namepattern, startdir = sys.argv[1], sys.argv[2] 
    for name in find(namepattern, startdir): print (name) 

Ich denke, dass ich eine neue Funktion definieren muß (das heißt, def ftp()) diese Funktionalität oben, um den Code hinzuzufügen. Ich fürchte jedoch, dass die os.walk-Funktion standardmäßig nur die Verzeichnisbäume des Computers ausführen wird, von dem der Code ausgeführt wird.

Gibt es eine Möglichkeit, dass ich die Funktionalität von os.walk erweitern kann, um einen entfernten Verzeichnisbaum (über FTP) zu durchlaufen?

+0

https: // pypi .python.org/pypi/ftptool/0.5.1 –

+0

Ich versuche, alle Schnittstellen jenseits von 'ftplib' zu vermeiden. Ist das möglich? Disclaimer: Ich habe 'ftptool' bereits ausprobiert und konnte nicht erreichen, dass ich das mache, was ich will. Daher ist der obige Code ein Python-Remash des Linux-Befehls 'find'. Ich versuche, es zu erweitern, indem ich einen FTP-Schalter zu 'os.walk' integriere. – warship

+0

Wenn mir jemand zeigen kann, wie man das in 'ftptool' auf eine Weise umbildet, die für entfernte FTP-Datenbanken funktioniert, werde ich dies auch als eine Antwort akzeptieren. – warship

Antwort

1

Alles, was Sie brauchen, ist die Verwendung des ftplib Moduls des Pythons. Da os.walk() auf einem Breath-First-Suchalgorithmus basiert, müssen Sie die Verzeichnisse und Dateinamen bei jeder Iteration suchen und dann das reversive Traversing vom ersten Verzeichnis aus fortsetzen. Ich implementierte this algorithm vor etwa 2 Jahren für die Verwendung als das Herz von FTPwalker, die ein optimales Paket zum Durchlaufen extrem großer Verzeichnisbäume über FTP ist.

from os import path as ospath 


class FTPWalk: 
    """ 
    This class is contain corresponding functions for traversing the FTP 
    servers using BFS algorithm. 
    """ 
    def __init__(self, connection): 
     self.connection = connection 

    def listdir(self, _path): 
     """ 
     return files and directory names within a path (directory) 
     """ 

     file_list, dirs, nondirs = [], [], [] 
     try: 
      self.connection.cwd(_path) 
     except Exception as exp: 
      print ("the current path is : ", self.connection.pwd(), exp.__str__(),_path) 
      return [], [] 
     else: 
      self.connection.retrlines('LIST', lambda x: file_list.append(x.split())) 
      for info in file_list: 
       ls_type, name = info[0], info[-1] 
       if ls_type.startswith('d'): 
        dirs.append(name) 
       else: 
        nondirs.append(name) 
      return dirs, nondirs 

    def walk(self, path='/'): 
     """ 
     Walk through FTP server's directory tree, based on a BFS algorithm. 
     """ 
     dirs, nondirs = self.listdir(path) 
     yield path, dirs, nondirs 
     for name in dirs: 
      path = ospath.join(path, name) 
      yield from self.walk(path) 
      # In python2 use: 
      # for path, dirs, nondirs in self.walk(path): 
      #  yield path, dirs, nondirs 
      self.connection.cwd('..') 
      path = ospath.dirname(path) 

nun diese Klasse für verwenden, können Sie einfach ein Verbindungsobjekt mit ftplib Modul erstellen und übergeben Sie die das Objekt zu FTPWalk Objekt und nur Schleife über die walk() Funktion:

In [2]: from test import FTPWalk 

In [3]: import ftplib 

In [4]: connection = ftplib.FTP("ftp.uniprot.org") 

In [5]: connection.login() 
Out[5]: '230 Login successful.' 

In [6]: ftpwalk = FTPWalk(connection) 

In [7]: for i in ftpwalk.walk(): 
      print(i) 
    ...:  
('/', ['pub'], []) 
('/pub', ['databases'], ['robots.txt']) 
('/pub/databases', ['uniprot'], []) 
('/pub/databases/uniprot', ['current_release', 'previous_releases'], ['LICENSE', 'current_release/README', 'current_release/knowledgebase/complete', 'previous_releases/', 'current_release/relnotes.txt', 'current_release/uniref']) 
('/pub/databases/uniprot/current_release', ['decoy', 'knowledgebase', 'rdf', 'uniparc', 'uniref'], ['README', 'RELEASE.metalink', 'changes.html', 'news.html', 'relnotes.txt']) 
... 
... 
... 
0

Im dies zu übernehmen gehen ist, was Sie wollen ... obwohl ich wirklich keine Ahnung haben,

ssh = paramiko.SSHClient() 
ssh.connect(server, username=username, password=password) 
ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("locate my_file.txt") 
print ssh_stdout 

dies den Remote-Server erfordern die mlocate Paket `sudo apt-get install mlocate haben; sudo updatedb();

+0

Einige Datenbanken, die ich verbinde, haben diesen Fehler: 'paramiko.ssh_exception.S SHException: Server 'ftp.server.org' wurde nicht in known_hosts gefunden. Bedeutet das, dass ich ihnen mit Paramiko nicht zuhauen kann? Ich werde den "mlocate" -Ansatz versuchen und ein Update veröffentlichen. – warship

+1

@warship Das ist offensichtlich, solche Fehler mit einem solchen Protokoll zu bekommen. Die Essenz von SSH ist die sichere Verbindung. – Kasramvd

Verwandte Themen