Extender la función os.walk de Python en el servidor FTP

¿Cómo puedo hacer que os.walk atraviese el árbol de directorios de una base de datos FTP (ubicada en un servidor remoto)? La forma en que se estructura el código ahora es (comentarios proporcionados):

 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) 

Estoy pensando que necesito definir una nueva función (es decir, def ftp() ) para agregar esta funcionalidad al código anterior. Sin embargo, me temo que la función os.walk , de forma predeterminada, solo recorrerá los árboles de directorios de la computadora desde la que se ejecuta el código.

¿Hay alguna forma en que pueda extender la funcionalidad de os.walk para poder atravesar un árbol de directorios remoto (a través de FTP)?

Todo lo que necesitas es utilizar el módulo ftplib de python. Como os.walk() se basa en un algoritmo de búsqueda de Breadth-first, necesita encontrar los directorios y los nombres de los archivos en cada iteración, luego continúe el recorrido recursivamente desde el primer directorio. Implementé este algoritmo hace aproximadamente 2 años para usarlo como el corazón de FTPwalker , que es un paquete óptimo para atravesar árboles de directorios extremadamente grandes a través de FTP.

 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) 

Ahora, para usar esta clase, puede simplemente crear un objeto de conexión usando el módulo ftplib y pasar el objeto a FTPWalk y simplemente recorrer la función walk() :

 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']) ... ... ... 

Voy a asumir que esto es lo que quieres … aunque realmente no tengo idea

 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 

esto requerirá que el servidor remoto tenga el paquete mlocate `sudo apt-get install mlocate; sudo updatedb ();