12

内容が不明なディレクトリをSSH経由で再帰的にダウンロードしたいので、Paramikoを試しています。ディレクトリをアップロードする方法の例をいくつか見てきましたが、再帰的なダウンロードをカバーするものはありません。

ディレクトリ内のすべてのアイテムを一覧表示できますが、アイテムがファイル(ダウンロードする)なのかディレクトリ(再帰的に呼び出す)なのかを知る方法を見つけることができませんでした。

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()

では、アイテムがファイルなのかディレクトリなのかをどうやって知ることができますか?

4

7 に答える 7

11
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

... sftpParamikoSFTP接続が開いていると仮定します。

于 2011-11-29T08:08:10.753 に答える
3

古い質問ですが、私が思いついた解決策は非常にうまく機能します。少しずさんです(型キャストやスラッシュなど)が、機能します。

これはfabric.api.local、宛先にディレクトリを作成するために使用されることに注意してください。

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)
于 2013-04-10T17:12:30.993 に答える
2

Paramikoは再帰操作をサポートしていません。

しかし、実装は簡単です。

import os
from stat import S_ISDIR, S_ISREG
def get_r_portable(sftp, remotedir, localdir):
    for entry in sftp.listdir_attr(remotedir):
        remotepath = remotedir + "/" + entry.filename
        localpath = os.path.join(localdir, entry.filename)
        mode = entry.st_mode
        if S_ISDIR(mode):
            try:
                os.mkdir(localpath)
            except OSError:     
                pass
            get_r_portable(sftp, remotepath, localpath)
        elif S_ISREG(mode):
            sftp.get(remotepath, localpath)

pysftpを使用することもできます。これは、Python風のルックアンドフィールを持ち、再帰操作をサポートするParamikoのラッパーです。見る

または、LinuxからのPython pysftp get_rに対する私の答えを参照してください。Linuxでは正常に動作しますが、Windowsでは動作しません。

しかし、pysftpは放棄されたプロジェクトのように思われるので、Paramikoを使い続ける方がよいでしょう。

于 2018-11-30T10:58:56.367 に答える
2

2021年に機能するDanLaMannaの回答の小さな更新。

import paramiko
import os
from stat import S_ISDIR, S_ISREG    

def sftp_get_recursive(path, dest, sftp):
    item_list = sftp.listdir_attr(path)
    dest = str(dest)
    if not os.path.isdir(dest):
        os.makedirs(dest, exist_ok=True)
    for item in item_list:
        mode = item.st_mode
        if S_ISDIR(mode):
            sftp_get_recursive(path + "/" + item.filename, dest + "/" + item.filename, sftp)
        else:
            sftp.get(path + "/" + item.filename, dest + "/" + item.filename)

transport = paramiko.Transport((host, port))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)
sftp_get_recursive(remote_path, local_path, sftp)
sftp.close()
于 2021-10-20T07:01:37.717 に答える
1

sftpオブジェクトのstat()メソッドを使用できます。

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

于 2011-07-13T12:05:38.520 に答える
1

他の属性の中でも特にstat()メソッドは、アクセス許可を返します。d(たとえば、drwxrwxrwx)は、それがディレクトリであることを示します。

例として:

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

出力の解釈:01fifo02文字特殊04ディレクトリ06ブロック特殊10通常ファイル12シンボリックリンク14ソケット

于 2012-03-14T07:44:47.923 に答える
-6

LinuxまたはUnixライクを使用している場合。Uはpopenで'file'ユーティリティを使用できます。または、単純なuはos.path.isdir()=)を使用できます

于 2011-07-13T08:15:25.580 に答える