来自 Linux 的 Python pysftp get_r 在 Linux 上运行良好,但在 Windows 上不起作用 [英] Python pysftp get_r from Linux works fine on Linux but not on Windows

查看:18
本文介绍了来自 Linux 的 Python pysftp get_r 在 Linux 上运行良好,但在 Windows 上不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 Python 2.7 使用 SFTP 递归地将包含文件和子文件夹的整个目录结构从 Linux 服务器复制到本地计算机(Windows 和 Linux).

I would like to copy an entire directory structure with files and subfolders recursively using SFTP from a Linux server to a local machine (both Windows and Linux) using Python 2.7.

我可以在同一台机器上使用 WinSCP ping 服务器并下载文件.

I am able to ping the server and download the files using WinSCP from the same machine.

我尝试了以下代码,在 Linux 上运行良好,但在 Windows 上不起作用.

I tried the following code, works fine on Linux but not on Windows.

我试过/os.join,都给我同样的错误,也检查了权限.

I tried , /, os.join, all gives me same error, checked permissions as well.

import os
import pysftp

cnopts = pysftp.CnOpts()
cnopts.hostkeys = None    # disable host key checking.
sftp=pysftp.Connection('xxxx.xxx.com', username='xxx', password='xxx', cnopts=cnopts)
sftp.get_r('/abc/def/ghi/klm/mno', 'C:pqr', preserve_mtime=False)

File "<stdin>", line 1, in <module> File "C:Python27libsite-packagespysftp_init_.py", line 311, in get_r preserve_mtime=preserve_mtime)
File "C:Python27libsite-packagespysftp_init_.py", line 249, in get self._sftp.get(remotepath, localpath, callback=callback)
File "C:Python27libsite-packagesparamikosftp_client.py", line 769, in get with open(localpath, 'wb') as fl: IOError: [Errno 2] No such file or directory: u'C:\pqr\./abc/def/ghi/klm/mno/.nfs0000000615c569f500000004' 

推荐答案

确实,pysftp get_r 在 Windows 上不起作用.它对远程 SFTP 路径使用 os.sepos.path 函数,这是怎么回事,因为 SFTP 路径总是使用正斜杠.

Indeed, pysftp get_r does not work on Windows. It uses os.sep and os.path functions for remote SFTP paths, what is wrong, as SFTP paths always use a forward slash.

但您可以轻松实现便携式替换.

But you can easily implement a portable replacement.

import os
from stat import S_ISDIR, S_ISREG

def get_r_portable(sftp, remotedir, localdir, preserve_mtime=False):
    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, preserve_mtime)
        elif S_ISREG(mode):
            sftp.get(remotepath, localpath, preserve_mtime=preserve_mtime)

像这样使用:

get_r_portable(sftp, '/abc/def/ghi/klm/mno', 'C:\pqr', preserve_mtime=False) 


请注意,如果您不想使用 pysftp,可以轻松修改上述代码以直接与 Paramiko 一起使用.Paramiko SFTPClient 也有 listdir_attrget 方法.唯一的区别是 Paramiko 的 get 没有 preserve_mtime 参数/功能(但可以轻松实现,如果需要的话).


Note that the above code can be easily modified to work with Paramiko directly, in case you do not want to use pysftp. The Paramiko SFTPClient class also has the listdir_attr and get methods. The only difference is that the Paramiko's get does not have the preserve_mtime parameter/functionality (but it can be implemented easily, if you need it).

可能的代码修改:

有关 put_r 的类似问题,请参阅:
Python pysftp put_r 在 Windows 上不起作用

For a similar question about put_r, see:
Python pysftp put_r does not work on Windows

旁注:不要禁用主机密钥检查".您正在失去对MITM 攻击的保护.

Side note: Do not "disable host key checking". You are losing a protection against MITM attacks.

有关正确的解决方案,请参阅使用 pysftp 验证主机密钥.

For a correct solution, see Verify host key with pysftp.

这篇关于来自 Linux 的 Python pysftp get_r 在 Linux 上运行良好,但在 Windows 上不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆