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

pysftp listdir_attr在含文件目录返回空值问题求助

SFTP扫描工具子目录listdir_attr返回空的排查方案

问题描述

我开发了一款用于扫描SFTP服务器并进行数据统计分析的小工具,代码在多数服务器上运行正常,但在某一特定服务器上出现异常:仅能列出顶层目录,进入子目录后listdir_attr返回空值,无任何报错信息。排查了连接选项但未发现相关影响因素,求问类似问题的排查方向。

工具代码

import pysftp
import os


class Connector:

    def __init__(self, host: str, user: str, password: str, port: int = 22, root: str = "."):
        ops = pysftp.CnOpts()
        ops.hostkeys = None
        self.root = root
        self.client = pysftp.Connection(host=host, username=user, password=password, port=port, cnopts=ops)
        self.stats = list()

    def __looper(self, folder):
        for f in self.client.listdir_attr(folder):
            f.attr["path"] = folder
            f.attr["props"] = f.longname[:10]
            self.stats.append(f)
            if f.longname.startswith("d"):
                self.__looper(os.path.join(folder, f.filename))

    def build_stats(self):
        self.__looper(self.root)
        self.client.close()
        return self.stats

排查方向与解决方案

  • 权限验证:先用FileZilla等通用SFTP客户端登录目标服务器,手动尝试进入子目录并查看内容。如果客户端也无法列出子目录,说明是服务器端对当前用户的子目录权限限制,联系管理员调整权限即可。
  • 路径分隔符问题:代码中用os.path.join拼接路径,该方法会随系统环境生成不同分隔符(Windows下是\),而多数SFTP服务器只认可/作为路径分隔符。替换成手动拼接:f"{folder}/{f.filename}",避免系统依赖的格式问题。
  • 绕过pysftp封装:部分定制化/老旧SFTP服务器可能与pysftp的listdir_attr实现不兼容,改用paramiko(pysftp的底层依赖)的原生方法拆分逻辑:先通过listdir获取文件名,再逐个调用stat获取属性,示例如下:
    def __looper(self, folder):
        filenames = self.client.listdir(folder)
        for filename in filenames:
            full_path = f"{folder}/{filename}"
            attr = self.client.stat(full_path)
            # 构造兼容原逻辑的对象结构
            sftp_file = type('SFTPFile', (), {
                'filename': filename,
                'longname': f"{ 'd' if attr.st_mode & 0o40000 else '-' }rwxrwxrwx",
                'attr': attr.__dict__
            })()
            sftp_file.attr["path"] = folder
            sftp_file.attr["props"] = sftp_file.longname[:10]
            self.stats.append(sftp_file)
            if attr.st_mode & 0o40000:  # 判断是否为目录
                self.__looper(full_path)
    
  • 查看服务器日志:联系服务器管理员查看SFTP服务的运行日志,确认是否存在针对子目录列表请求的拦截、错误记录或特殊配置限制。
  • 特殊字符目录验证:如果子目录名称包含空格、非ASCII字符,打印拼接后的路径检查格式是否正确,必要时对文件名做编码处理后再拼接路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:47:39