2017-09-01 14 views
0

Je veux imiter le comportement de la célèbre commande Linux rsync où il copie le répertoire entier de "test" si le "/" n'est pas spécifié à la fin d'un répertoire et copie tout à l'intérieur du " test/"lorsque le"/"est présent. Mon locale dossier "test" est une structure comme ceci:Copier des répertoires en utilisant Paramiko SFTP

test 
. 
├── fileA.txt 
├── fileB.txt 
├── test1 
│   └── test3 
│    └── file3.txt 
└── test2 
    └── file2.txt 

Pour copier l'intégralité du dossier de test local au serveur distant dans rsync:

rsync -avzP test [email protected]:/home/ 

A l'intérieur du répertoire du remotehost serait

home 
. 
|__ test 
    ├── fileA.txt 
    ├── fileB.txt 
    ├── test1 
    │   └── test3 
    │    └── file3.txt 
    └── test2 
     └── file2.txt 

Exemple A

Pour copier tout à l'intérieur du dossier "test" local exclut lui-même:

rsync -avzP test/ [email protected]:/home/ 

La structure répertoire serait:

home/ 
. 
├── fileA.txt 
├── fileB.txt 
├── test1 
│   └── test3 
│    └── file3.txt 
└── test2 
    └── file2.txt 

Exemple B

Le code je n'est pas Travaillant pour l'exemple B. J'ai pensé diviser les chemins et me débarrasser du "test" puis copier tout à l'intérieur de celui-ci mais cela ne m'amène qu'à un interminable, imbriqué, pour des boucles. Une autre idée consiste à utiliser os.listdir. Si c'est un répertoire, liste à nouveau le répertoire et copie le contenu dans ce répertoire. C'est encore une autre boucle infinie. La structure arborescente ci-dessus est un exemple simplifié, mais dans la réalité, nous savons tous que le répertoire peut avoir 5 niveaux de profondeur. Comment puis-je implémenter l'exemple B?

def put (self, localpath, remotepath): 

     sftp = self.ssh.open_sftp() 

     # Create remote directory if it doesn't exist 
     try: 
      sftp.stat (remotepath) 
     except FileNotFoundError: 
      sftp.mkdir (remotepath) 

     if os.path.isfile (localpath): 
      # Obtain file name from local path & append to remote path 
      path = os.path.split (localpath)  # Returns a tuple (directory, filename) 
      remote_filename = os.path.join (remotepath, path [1]) 
      print (' Copying %s' % remote_filename) 
      sftp.put (localpath, remote_filename) 

     elif os.path.isdir (localpath): 
      p = os.path.join (remotepath, localpath) 
      try: 
       sftp.stat (p) 
      except FileNotFoundError: 
       sftp.mkdir (p) 

      for dirpath, dirnames, filenames in os.walk (localpath): 
       # Traverse into each child directory and create sub directory if it doesn't exist 
       if dirnames: 
        for dirname in dirnames: 
         subdir = os.path.join (dirpath, dirname) 
         try: 
          sftp.stat (subdir) 
         except FileNotFoundError: 
          sftp.mkdir (subdir) 

       for filename in filenames: 
        local_filename = os.path.join (dirpath, filename) 
        remote_filename = os.path.join (remotepath, local_filename) 
        sftp.put (local_filename, remote_filename) 

Répondre

0

Je l'ai compris. Ce n'est pas le plus joli mais fonctionnel. Si quelqu'un a mieux, plus propre, et plus pythonique de le faire, s'il vous plaît partager.

def put (self, localpath, remotepath): 

    sftp = self.ssh.open_sftp() 

    # Create remote directory if it doesn't exist 
    try: 
     sftp.stat (remotepath) 
    except FileNotFoundError: 
     sftp.mkdir (remotepath) 

    if os.path.isfile (localpath): 
     # Obtain file name from local path & append to remote path 
     path = os.path.split (localpath)  # Returns a tuple (directory, filename) 
     remote_filename = os.path.join (remotepath, path [1]) 
     print (' Copying %s' % remote_filename) 
     sftp.put (localpath, remote_filename) 

    elif os.path.isdir (localpath): 
     if localpath.endswith ('/'): 
      for dirpath, dirnames, filenames in os.walk (localpath): 
       # Change local dirpath to match remote path. Ex: local/dir/.. to remote/dir/... 
       remotedir = dirpath.split ('/')    # remotedir = [local, dir1, dir2, ...] 
       remotedir [0] = remotepath.rstrip ('/')  # remotedir = [/remote, dir1, dir2, ...] 
       remotedir = '/'.join (remotedir) 

       # Traverse into each child directory and create sub directory if it doesn't exist on remote host 
       if dirnames: 
        for dirname in dirnames: 
         subdir = os.path.join (remotedir, dirname) 

         try: 
          sftp.stat (subdir) 
         except FileNotFoundError: 
          sftp.mkdir (subdir) 

       for filename in filenames: 
        localdir = os.path.join (dirpath, filename) 
        remotefile = os.path.join (remotedir, filename) 
        print (' Copying %s' % localdir) 
        sftp.put (localdir, remotefile) 
     else: 
      # Create path /remote/local/dir1... 
      p = os.path.join (remotepath, localpath) 

      try: 
       sftp.stat (p) 
      except FileNotFoundError: 
       sftp.mkdir (p) 

      for dirpath, dirnames, filenames in os.walk (localpath): 
       if dirnames: 
        for dirname in dirnames: 
         subdir = os.path.join (dirpath, dirname) 
         remotedir = os.path.join (remotepath, subdir) 

         try: 
          sftp.stat (remotedir) 
         except FileNotFoundError: 
          sftp.mkdir (remotedir) 

       for filename in filenames: 
        local_filename = os.path.join (dirpath, filename) 
        remote_filename = os.path.join (remotepath, local_filename) 
        print (' Copying %s' % local_filename) 
        sftp.put (local_filename, remote_filename) 
    else: 
     print ('File or directory not found.') 

End résultats:

Exemple A:

>>> ssh.put ('test', '/home/user/') 
Copying test/fileA.txt 
Copying test/fileB.txt 
Copying test/test1/test3/file3.txt 
Copying test/test2/file2.txt 
Completed! 

-sh-4.1$ ls -lh test/* 
-rw-r----- 1 user users 0 Sep 1 23:43 test/fileA.txt 
-rw-r----- 1 user users 0 Sep 1 23:43 test/fileB.txt 

test/test1: 
total 4.0K 
drwxr-x--- 2 user users 4.0K Sep 1 23:43 test3 

test/test2: 
total 0 
-rw-r----- 1 user users 0 Sep 1 23:43 file2.txt 

-sh-4.1$ ls -lh test/*/* 
-rw-r----- 1 user users 0 Sep 1 23:43 test/test2/file2.txt 

test/test1/test3: 
total 0 
-rw-r----- 1 user users 0 Sep 1 23:43 file3.txt 
-sh-4.1$ 

Exemple B:

>>> ssh.put ('test/', '/home/user/') 
    Copying test/fileA.txt 
    Copying test/fileB.txt 
    Copying test/test1/test3/file3.txt 
    Copying test/test2/file2.txt 
Completed! 

-sh-4.1$ pwd 
/home/user 
-sh-4.1$ ls -lh 
total 108K 
-rw-r----- 1 user users 0 Sep 1 23:43 fileA.txt 
-rw-r----- 1 user users 0 Sep 1 23:43 fileB.txt 
drwxr-x--- 3 user users 4.0K Sep 1 23:43 test1 
drwxr-x--- 2 user users 4.0K Sep 1 23:43 test2 

-sh-4.1$ ls -lh test1 test2 
test1: 
total 4.0K 
drwxr-x--- 2 user users 4.0K Sep 1 23:43 test3 

test2: 
total 0 
-rw-r----- 1 user users 0 Sep 1 23:43 file2.txt 

-sh-4.1$ ls -lh test1/test3/ 
total 0 
-rw-r----- 1 user users 0 Sep 1 23:43 file3.txt 
-sh-4.1$