来自 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.sep
和 os.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_attr
和 get
方法.唯一的区别是 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.