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

求助:用Python递归获取文件绝对路径、UID及所有者时脚本执行报错

嘿,我来帮你搞定这个递归列文件的需求!我写了两个可行的Python脚本,还会帮你排查可能导致末尾报错的常见问题~

完整实现脚本(Unix-like系统:Linux/macOS)

这个脚本支持命令行传参,能递归遍历指定目录,输出每个文件的UID、所有者名称和绝对路径,还会处理权限不足、无对应用户的UID等异常情况:

import os
import pwd
from argparse import ArgumentParser

def list_files_with_owner(root_dir):
    # 递归遍历目录结构,获取当前路径、子目录、文件列表
    for dirpath, _, filenames in os.walk(root_dir):
        for filename in filenames:
            # 拼接并转换为绝对路径
            file_path = os.path.abspath(os.path.join(dirpath, filename))
            try:
                # 获取文件的状态信息
                stat_info = os.stat(file_path)
                uid = stat_info.st_uid
                # 根据UID获取用户名,处理UID无对应用户的情况
                try:
                    owner = pwd.getpwuid(uid).pw_name
                except KeyError:
                    owner = f"UID_{uid}"
                # 格式化输出,让列对齐更美观
                print(f"{uid:<6} {owner:<15} {file_path}")
            except PermissionError:
                print(f"⚠️ 权限不足,无法访问: {file_path}")
            except Exception as e:
                print(f"❌ 处理文件 {file_path} 时出错: {str(e)}")

if __name__ == "__main__":
    parser = ArgumentParser(description="递归列出目录下所有文件的UID、所有者和绝对路径")
    parser.add_argument("directory", nargs="?", default=os.getcwd(), help="要遍历的目录(默认当前目录)")
    args = parser.parse_args()
    list_files_with_owner(args.directory)

如果你更喜欢用更现代的pathlib模块,这个版本更简洁:

from pathlib import Path
import pwd
from argparse import ArgumentParser

def list_files_with_owner(root_dir):
    root = Path(root_dir).resolve()  # 获取绝对路径
    # 递归匹配所有条目,只处理文件(排除目录)
    for file_path in root.glob('**/*'):
        if file_path.is_file():
            try:
                stat_info = file_path.stat()
                uid = stat_info.st_uid
                try:
                    owner = pwd.getpwuid(uid).pw_name
                except KeyError:
                    owner = f"UID_{uid}"
                print(f"{uid:<6} {owner:<15} {file_path}")
            except PermissionError:
                print(f"⚠️ 权限不足,无法访问: {file_path}")
            except Exception as e:
                print(f"❌ 处理文件 {file_path} 时出错: {str(e)}")

if __name__ == "__main__":
    parser = ArgumentParser(description="递归列出目录下所有文件的UID、所有者和绝对路径")
    parser.add_argument("directory", nargs="?", default=Path.cwd(), help="要遍历的目录(默认当前目录)")
    args = parser.parse_args()
    list_files_with_owner(args.directory)
关键功能说明
  • 递归遍历:用os.walk或pathlib.glob('**/*')实现目录的深度遍历
  • 文件信息获取:通过os.stat或Path.stat()拿到文件的UID
  • 所有者解析:用pwd.getpwuid()把UID转换成用户名,同时捕获KeyError处理无对应用户的UID(比如某些系统文件的UID)
  • 异常处理:捕获PermissionError避免脚本因权限不足崩溃,其他异常也会给出具体提示
为什么你的脚本会在末尾报错?

大概率是没处理这些常见问题:

  1. 权限不足:遍历到没有读权限的文件/目录时,直接抛出异常终止脚本
  2. 无效UID:某些文件的UID没有对应的系统用户,调用pwd.getpwuid()会抛出KeyError
  3. 符号链接循环:如果脚本没排除符号链接,可能陷入递归死循环
  4. 未处理其他异常:比如文件被删除、路径非法等情况,没加异常捕获就会导致脚本中途崩溃

上面的脚本已经把这些情况都处理了,不会出现执行到末尾报错的问题~

Windows系统适配方案

Windows没有pwd模块,如果你需要在Windows上运行,可以替换获取所有者的逻辑,用pywin32库:

  1. 先安装依赖:pip install pywin32
  2. 替换所有者获取的代码:
import win32security

def get_file_owner(file_path):
    sd = win32security.GetFileSecurity(file_path, win32security.OWNER_SECURITY_INFORMATION)
    owner_sid = sd.GetSecurityDescriptorOwner()
    name, domain, _ = win32security.LookupAccountSid(None, owner_sid)
    return f"{domain}\\{name}"

然后在脚本中用owner = get_file_owner(file_path)替代原来的pwd相关逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:35:32