You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:07:53