2017-09-01 83 views
0

"/"がディレクトリの最後に指定されていない場合に "test"からディレクトリ全体をコピーし、 "ディレクトリ"内のすべてをコピーする有名なLinux rsyncコマンドの動作を模倣したい。 「/」が存在するときは「テスト/」を選択します。私の地元の「テスト」フォルダがそうのような構造である:rsyncのリモートサーバーへの全体のローカルテスト用フォルダをコピーするにはParamiko SFTPを使用してディレクトリをコピーする

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

:remotehostのホームディレクトリ内

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

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

例A

コピーするには

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

ホームディレクトリの構造は次のようになります:自体を除く地域の "テスト" フォルダ内のすべて

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

例B

は、私が持っているコードではありません私はパスを分割し、 "テスト"を取り除き、その中のすべてをコピーすることを考えましたが、それは無限のネストされたforループにつながります。もう一つのアイデアはos.listdirを使うことです。それがディレクトリの場合は、ディレクトリを再度一覧表示し、そのディレクトリ内の内容をコピーします。これはもう一つの無限ループです。上記のツリー構造は単純化された例ですが、現実には、ディレクトリが5レベル深くなる可能性があります。 Example 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) 

答えて

0

私はそれを理解しました。それは一番美しいものではありませんが、機能的です。もし誰かがより良く、よりクリーンで、より平凡な方法をしているなら、分かち合ってください。

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

最終結果:

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

例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$ 
関連する問題