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

Python paramiko调用sftp.get下载SFTP文件时报Error13访问拒绝

问题现象

从SFTP服务器下载文件到本地时触发Error 13 Access denied访问拒绝错误,分步排查时SFTP连接、远程目录枚举、本地路径访问均正常,仅执行sftp.get(filepath, localpath)时报错。
问题复现代码如下:

from os import listdir
import os
from threading import local
import paramiko
paramiko.util.log_to_file("Client_Update.log")

VersionNumber = input("Please enter the version number to download: ")
print("Version Number is " + VersionNumber)

# Create directory for Version
try:
    os.mkdir("C:\\ClientSoftware\\" +VersionNumber)
    print("Directory created successfully!")
except:
    print("Failed to create Directory")

# Open a transport
host,port = "host IP",22
transport = paramiko.Transport((host,port))

# Auth   
try: 
    username,password = "test","test123"
    transport.connect(None,username,password)

# Access SFTP    
    sftp = paramiko.SFTPClient.from_transport(transport)
    print("...Connection Succesful")
    listdir()
except NameError:
    print("....Connection Failed")
except:
    print("An Error Occured - Please contact Admin for further details")

# Download
try :
    filepath = "/WebService/Client Software/Application Files/" + VersionNumber+"/"
    print("Version Found Succesfully!")
    dirlist = sftp.listdir(filepath)
    print ("Dirlist:", dirlist)
    
    try:
       
        localpath = "C:\\ClientSoftware\\" +VersionNumber+"\\motaDataClientSoftware.7z"
        print (localpath)
        print("local directory found succesfully!")
    except:
        print("Local Path not found, please check if localpath C:\ClientSoftware exists")
    try:
        sftp.get(filepath, localpath)
    except:
        print("An Error Occurred with downloading off SFTP")
        print(filepath, localpath)
except:
    print("FilePath Does not exist, Please check if path exists on SFTP and check your version Number exists")
  
# Close
try:
    if sftp: sftp.close()
    if transport: transport.close()
except:
    print("SFTP not open, failed to close")
问题根因

报错由两处核心逻辑错误共同导致:

  • 远程路径参数错误:传入sftp.get()的filepath是版本号对应的远程目录路径,并非目标7z压缩包的完整文件路径。Paramiko的get()方法仅支持下载单个文件,传入目录路径会触发底层路径访问异常,且被代码中的裸except捕获,无法透出真实错误信息。
  • 本地路径权限不足:Windows默认UAC权限规则下,普通权限进程直接在C:\盘根目录创建文件夹、写入文件会被系统拦截,触发访问拒绝;在部署了企业安全管控的设备上,C盘根目录默认禁止普通用户写入。
  • 附加代码bug:存在无效导入from threading import local、无参数调用listdir()(会直接抛出参数缺失错误)、裸except吞掉所有异常栈的问题,严重干扰问题排查。
修复方案
  • 修正远程文件路径:将远程目录与目标文件名拼接为完整的文件路径,禁止直接传入目录给get()方法
  • 调整本地存储路径:将文件存储位置改到当前用户目录下,避免C盘根目录的权限限制;如果必须存在C盘根目录,右键选择「以管理员身份运行」启动脚本
  • 移除所有裸except逻辑,打印真实错误信息方便定位问题,清理无效代码
  • 下载前增加远程文件存在性校验、本地目录自动创建逻辑,避免前置步骤失败导致后续报错
修复后可运行代码
import os
import paramiko
paramiko.util.log_to_file("Client_Update.log")

VersionNumber = input("Please enter the version number to download: ")
print("Version Number is " + VersionNumber)

# 本地路径改到当前用户目录,规避C盘根目录权限问题
local_base_path = os.path.expanduser("~\\ClientSoftware")
version_local_path = os.path.join(local_base_path, VersionNumber)
# 自动递归创建目录,已存在时不报错
os.makedirs(version_local_path, exist_ok=True)
print("Local directory checked/created successfully")

host, port = "host IP", 22
transport = paramiko.Transport((host, port))
sftp = None

try:
    username, password = "test", "test123"
    transport.connect(None, username, password)
    sftp = paramiko.SFTPClient.from_transport(transport)
    print("SFTP connection established")

    # 拼接远程文件完整路径,SFTP使用正斜杠
    remote_dir = f"/WebService/Client Software/Application Files/{VersionNumber}/"
    remote_file = f"{remote_dir}motaDataClientSoftware.7z"
    print(f"Target remote file path: {remote_file}")

    # 校验远程目录和文件存在
    dir_files = sftp.listdir(remote_dir)
    print("Remote directory file list:", dir_files)
    if "motaDataClientSoftware.7z" not in dir_files:
        raise FileNotFoundError("Target 7z package not found in remote directory")

    # 拼接本地文件存储路径
    local_file = os.path.join(version_local_path, "motaDataClientSoftware.7z")
    print(f"Local save path: {local_file}")

    # 执行文件下载
    sftp.get(remote_file, local_file)
    print("File download completed successfully")

except Exception as e:
    print(f"Operation failed, error details: {repr(e)}")
finally:
    # 确保连接正常关闭
    if sftp:
        sftp.close()
    if transport:
        transport.close()
    print("SFTP connection closed")
额外排查项

如果调整后仍报权限错误,逐一检查以下项:

  • 确认SFTP账号对远程目标7z文件有读权限,而非仅拥有目录列表权限
  • 检查本地杀毒软件、终端安全管控软件是否拦截了脚本的文件写入行为
  • 确认远程路径无拼写错误,SFTP路径统一使用正斜杠,不要混用Windows反斜杠

内容的提问来源于stack exchange,提问作者joshua segal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:06:29