2017-09-01 7 views
0

Ich möchte das Verhalten des berühmten Linux rsync-Befehls nachahmen, wo es das gesamte Verzeichnis von "test" kopiert, wenn das "/" nicht am Ende eines Verzeichnisses angegeben ist und kopiert alles innerhalb der " test/"wenn das"/"vorhanden ist. Meine lokalen Ordner "Test" ist Struktur wie folgt:Kopieren von Verzeichnissen mit Paramiko SFTP

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

den gesamten lokalen Testordner auf Remote-Server in rsync zu kopieren:

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

Innerhalb Home-Verzeichnis des entfernter_host wäre

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

Beispiel A

Kopieren alles in den lokalen Ordner "Test" ohne selbst:

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

Die Struktur für Home-Verzeichnis wäre:

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

Beispiel B

Der Code, den ich habe, ist nicht Ich habe daran gedacht, die Pfade zu teilen und den "Test" loszuwerden, dann alles darin zu kopieren, aber es führt mich nur zu endlosen, verschachtelten For-Schleifen. Eine andere Idee ist es, os.listdir zu verwenden. Wenn es sich um ein Verzeichnis handelt, listen Sie das Verzeichnis erneut auf und kopieren Sie den Inhalt in dieses Verzeichnis. Dies ist noch eine weitere endlose Schleife. Die obige Baumstruktur ist ein vereinfachtes Beispiel, aber im wirklichen Leben wissen wir alle, dass das Verzeichnis 5 Ebenen tief sein könnte. Wie kann ich Beispiel B implementieren?

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) 

Antwort

0

Ich fand es heraus. Es ist nicht das schönste, aber funktional. Wenn jemand eine bessere, sauberere und pythischere Methode hat, teilen Sie es bitte mit.

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

Endergebnissen:

Beispiel 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$ 

Beispiel 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$ 
Verwandte Themen