Python 2.7 pysftp get_r递归下载:Linux正常Windows异常
Python 2.7 SFTP递归复制目录:Windows环境失败的排查与解决
先聊聊你的场景:你需要用Python 2.7写脚本,通过SFTP从Linux服务器把带文件和子文件夹的完整目录递归复制到本地(Windows/Linux都要支持)。现在同一机器能ping通服务器,WinSCP也能正常下载,但自己写的代码在Linux下没问题,Windows下彻底失效——各种路径写法(\、/、os.path.join)都试过,权限也检查过,还是不行。
先把你提到的代码补全(应该是漏了连接和复制的核心逻辑),方便大家定位问题:
import os import pysftp cnopts = pysftp.CnOpts() cnopts.hostkeys = None # 禁用主机密钥检查,注意生产环境不建议这么做 with pysftp.Connection('你的服务器地址', username='用户名', password='密码', cnopts=cnopts) as sftp: # 假设远程目录是'/remote/source',本地目录是'local/target' sftp.get_r('/remote/source', 'local/target')
可能的问题原因
- Windows路径的转义坑:Windows用
\做路径分隔符,但在Python字符串里\是转义字符,比如你写C:\test,Python会把\t解析成制表符,实际路径变成C:test,自然找不到目录。哪怕用os.path.join,pysftp的get_r方法在处理Windows路径时,可能还是会混淆Unix风格的路径分隔符。 - pysftp的
get_r方法Windows兼容性bug:pysftp的递归复制方法在Windows下处理目录创建时,可能会把Unix风格的路径直接套用到Windows上,导致无法正确创建子目录。 - Windows权限的细节问题:虽然你说检查过权限,但Windows的权限比Linux复杂——比如脚本是不是没以管理员身份运行?目标文件夹是不是被其他程序锁定了?或者用户没有创建子文件夹的权限?
具体解决办法
1. 统一用/作为路径分隔符
Windows下的Python其实支持/作为路径分隔符,不管是远程还是本地路径,全用/来写,比如本地路径写成C:/Users/你的用户名/target,彻底避开转义问题:
with pysftp.Connection('服务器地址', username='用户名', password='密码', cnopts=cnopts) as sftp: sftp.get_r('/remote/source', 'C:/Users/你的用户名/local_target')
2. 手动实现递归复制逻辑,避开pysftp的坑
如果get_r方法确实有兼容性问题,不如自己写递归逻辑,完全控制每一步:
import os import pysftp def sftp_recursive_copy(sftp, remote_dir, local_dir): # 先创建本地目录,不存在就新建 if not os.path.exists(local_dir): os.makedirs(local_dir) # 遍历远程目录下的所有文件和子目录 for entry in sftp.listdir_attr(remote_dir): remote_path = f"{remote_dir}/{entry.filename}" local_path = f"{local_dir}/{entry.filename}" # 判断是否是目录(通过Unix的权限位) if entry.st_mode & 0o40000: # 递归处理子目录 sftp_recursive_copy(sftp, remote_path, local_path) else: # 下载文件 sftp.get(remote_path, local_path) # 连接SFTP服务器 cnopts = pysftp.CnOpts() cnopts.hostkeys = None with pysftp.Connection('服务器地址', username='用户名', password='密码', cnopts=cnopts) as sftp: sftp_recursive_copy(sftp, '/remote/source_dir', 'C:/Users/你的用户名/local_dir')
3. 确认Windows本地权限细节
- 优先把目标文件夹放在用户自己的目录下(比如
C:/Users/你的用户名/Documents/),避免系统盘的权限限制; - 右键目标文件夹→属性→安全,确保当前用户有「写入」「创建文件/文件夹」的权限;
- 如果还是不行,试试以管理员身份运行Python脚本。
4. 考虑换用paramiko(或者升级依赖)
pysftp是基于paramiko的封装,Windows下可能pysftp的版本对Python 2.7支持不好。如果必须用Python 2.7,可以试试直接用paramiko实现递归复制,或者找一个兼容Python 2.7的最新pysftp版本(注意Python 2.7已经停止维护,长期来看建议升级到Python 3)。
内容的提问来源于stack exchange,提问作者user3399495
相关产品推荐
相关产品推荐

