Recursive directory download with Paramiko?

2019-01-18 05:56发布

I want to download a directory with unknown contents recursively via SSH and have been trying Paramiko. I have seen several examples how to upload directories but none that covers recursive download.

I can list all items in a directory but haven't been able to find a way of knowing if the item is a file (to download) or a directory (to call recursively).

transport = paramiko.Transport((MY_IP, 22))
transport.connect(username=MY_NAME, password=MY_PASS)
sftp = paramiko.SFTPClient.from_transport(transport)

file_list = sftp.listdir(path='/home/MY_HOME_DIR')
    for item in file_list:
        # Here is an item name... but is it a file or directory?
        print(item)
sftp.close()
transport.close()

So how do I know if an item is a file or if it is a directory?

6条回答
再贱就再见
2楼-- · 2019-01-18 06:03

If u using Linux or Unix-like. U can use 'file' utility with popen. Or simple u can use os.path.isdir() =)

查看更多
【Aperson】
3楼-- · 2019-01-18 06:11

You can use the stat() method of your sftp object:

http://www.lag.net/paramiko/docs/paramiko.SFTPClient-class.html

查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-18 06:12

stat() method among other attributes returns permissions. d (for example drwxrwxrwx) shows that it is directory.

As example:

dir = oct(sftp.stat(path).st_mode)
print dir[0:2]

output interpritation: 01 fifo 02 character special 04 directory 06 block special 10 regular file 12 symbolic link 14 socket

查看更多
趁早两清
5楼-- · 2019-01-18 06:12

Paramiko does not support recursive operations.

You can use pysftp. It's a wrapper around Paramiko that has more Python-ish look and feel and supports recursive operations. See

Or you can just base your code on pysftp source code. Or see my answer to Python pysftp get_r from Linux works fine on Linux but not on Windows.

查看更多
成全新的幸福
6楼-- · 2019-01-18 06:14

An old question, but a solution I came up with that works quite well, it's a little bit sloppy (typecasting and slashes and all) - but it does work.

Note this uses fabric.api.local to make the directories in the destination.

def sftp_get_recursive(path, dest, sftp=sftp):
    item_list = sftp.listdir(path)
    dest = str(dest)

    if not os.path.isdir(dest):
        local("mkdir %s" % dest)

    for item in item_list:
        item = str(item)

        if is_directory(path + "/" + item, sftp):
            sftp_get_recursive(path + "/" + item, dest + "/" + item, sftp)
        else:
            sftp.get(path + "/" + item, dest + "/" + item)
查看更多
老娘就宠你
7楼-- · 2019-01-18 06:16
from stat import S_ISDIR

def isdir(path):
  try:
    return S_ISDIR(sftp.stat(path).st_mode)
  except IOError:
    #Path does not exist, so by definition not a directory
    return False

...assuming sftp is an open Paramiko SFTP connection.

查看更多
登录 后发表回答