[英]Python pysftp get_r from Linux works fine on Linux but not on Windows
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.我想使用 Python 2.7 使用 SFTP 将带有文件和子文件夹的整个目录结构从 Linux 服务器递归地复制到本地机器(Windows 和 Linux)。
I am able to ping the server and download the files using WinSCP from the same machine.我能够 ping 服务器并使用 WinSCP 从同一台机器下载文件。
I tried the following code, works fine on Linux but not on Windows.我尝试了以下代码,在 Linux 上运行良好,但在 Windows 上运行良好。
I tried \
, /
, os.join
, all gives me same error, checked permissions as well.我试过\
, /
, os.join
,都给了我同样的错误,也检查了权限。
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:\Python27\lib\site-packages\pysftp_init_.py", line 311, in get_r preserve_mtime=preserve_mtime)
File "C:\Python27\lib\site-packages\pysftp_init_.py", line 249, in get self._sftp.get(remotepath, localpath, callback=callback)
File "C:\Python27\lib\site-packages\paramiko\sftp_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'
Indeed, pysftp get_r
does not work on Windows.事实上, pysftp get_r
在 Windows 上不起作用。 It uses os.sep
and os.path
functions for remote SFTP paths, what is wrong, as SFTP paths always use a forward slash.它对远程 SFTP 路径使用os.sep
和os.path
函数,这是错误的,因为 SFTP 路径总是使用正斜杠。
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)
Use it like:像这样使用它:
get_r_portable(sftp, '/abc/def/ghi/klm/mno', 'C:\\pqr', preserve_mtime=False)
Note that the above code can be easily modified to work with Paramiko directly, in case you do not want to use pysftp.请注意,上面的代码可以很容易地修改为直接使用 Paramiko,以防您不想使用 pysftp。 The Paramiko SFTPClient
class also has the listdir_attr
and get
methods. SFTPClient
类也有listdir_attr
和get
方法。 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).唯一的区别是 Paramiko 的get
没有preserve_mtime
参数/功能(但如果需要,它可以很容易地实现)。
And you should use Paramiko instead of pysftp, as pysftp seems to be a dead project.你应该使用 Paramiko 而不是 pysftp,因为 pysftp 似乎是一个死项目。 See pysftp vs. Paramiko .参见pysftp vs. Paramiko 。
Possible modifications of the code:可能的代码修改:
For a similar question about put_r
, see:有关put_r
的类似问题,请参阅:
Python pysftp put_r does not work on Windows Python pysftp put_r 在 Windows 上不起作用
Side note: Do not "disable host key checking" .旁注:不要“禁用主机密钥检查” 。 You are losing a protection against MITM attacks .您正在失去对MITM 攻击的保护。
For a correct solution, see Verify host key with pysftp .有关正确的解决方案,请参阅使用 pysftp 验证主机密钥。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.