如何用Python迁移ADLS大小写重复文件夹的ACL并清理冗余目录
解决Python环境下大小写重复文件夹的ACL迁移与清理问题
核心思路
- 从修复后的数据库导出标准大小写的目标文件夹名称列表(比如统一为小写或数据库指定的正确格式)
- 遍历目标根目录,识别所有与标准名称大小写不同但字符一致的冗余文件夹
- 将冗余文件夹的ACL权限合并/迁移到标准命名的文件夹
- 验证权限迁移完成后,删除冗余文件夹
分平台实现代码
Windows 环境(依赖pywin32库)
先安装依赖:pip install pywin32
import os import win32security import pywintypes import shutil def get_folder_acl(folder_path): """获取文件夹的ACL权限""" sd = win32security.GetFileSecurity(folder_path, win32security.DACL_SECURITY_INFORMATION) dacl = sd.GetSecurityDescriptorDacl() return dacl def set_folder_acl(folder_path, dacl): """将ACL权限应用到文件夹""" sd = win32security.GetFileSecurity(folder_path, win32security.DACL_SECURITY_INFORMATION) sd.SetSecurityDescriptorDacl(1, dacl, 0) win32security.SetFileSecurity(folder_path, win32security.DACL_SECURITY_INFORMATION, sd) def migrate_and_clean(root_dir, correct_names): # 构建小写映射,用于匹配大小写变体 correct_name_map = {name.lower(): name for name in correct_names} for folder_name in os.listdir(root_dir): folder_path = os.path.join(root_dir, folder_name) if not os.path.isdir(folder_path): continue lower_name = folder_name.lower() if lower_name not in correct_name_map: continue # 不在目标范围内,跳过 correct_name = correct_name_map[lower_name] if folder_name == correct_name: continue # 本身是正确命名,跳过 correct_path = os.path.join(root_dir, correct_name) if not os.path.exists(correct_path): print(f"警告:正确命名文件夹 {correct_name} 不存在,跳过迁移") continue try: # 获取并合并ACL redundant_acl = get_folder_acl(folder_path) correct_acl = get_folder_acl(correct_path) for i in range(redundant_acl.GetAceCount()): ace = redundant_acl.GetAce(i) correct_acl.AddAce(ace[0], ace[1]) set_folder_acl(correct_path, correct_acl) print(f"已迁移 {folder_name} 的ACL到 {correct_name}") # 删除冗余文件夹 shutil.rmtree(folder_path) print(f"已删除冗余文件夹 {folder_name}") except pywintypes.error as e: print(f"处理 {folder_name} 时出错: {e}") # 示例调用 if __name__ == "__main__": # 从数据库获取的正确文件夹名称列表 CORRECT_FOLDER_NAMES = ["Document", "Image", "Video"] ROOT_DIRECTORY = "D:/your_target_root" migrate_and_clean(ROOT_DIRECTORY, CORRECT_FOLDER_NAMES)
Linux/macOS 环境(依赖pylibacl库)
先安装依赖:pip install pylibacl
import os import acl import shutil def get_folder_acl(folder_path): """获取文件夹的ACL权限""" return acl.ACL(file=folder_path) def set_folder_acl(folder_path, acl_obj): """将ACL权限应用到文件夹""" acl_obj.applyto(folder_path) def migrate_and_clean(root_dir, correct_names): correct_name_map = {name.lower(): name for name in correct_names} for folder_name in os.listdir(root_dir): folder_path = os.path.join(root_dir, folder_name) if not os.path.isdir(folder_path): continue lower_name = folder_name.lower() if lower_name not in correct_name_map: continue correct_name = correct_name_map[lower_name] if folder_name == correct_name: continue correct_path = os.path.join(root_dir, correct_name) if not os.path.exists(correct_path): print(f"警告:正确命名文件夹 {correct_name} 不存在,跳过迁移") continue try: # 获取并合并ACL(避免重复添加规则) redundant_acl = get_folder_acl(folder_path) correct_acl = get_folder_acl(correct_path) for entry in redundant_acl: if entry not in correct_acl: correct_acl.append(entry) set_folder_acl(correct_path, correct_acl) print(f"已迁移 {folder_name} 的ACL到 {correct_name}") # 删除冗余文件夹 shutil.rmtree(folder_path) print(f"已删除冗余文件夹 {folder_name}") except Exception as e: print(f"处理 {folder_name} 时出错: {e}") # 示例调用 if __name__ == "__main__": CORRECT_FOLDER_NAMES = ["Document", "Image", "Video"] ROOT_DIRECTORY = "/your/target/root" migrate_and_clean(ROOT_DIRECTORY, CORRECT_FOLDER_NAMES)
关键注意事项
- 先备份:执行任何修改前,务必备份目标目录的所有文件和权限配置,避免数据丢失
- 权限要求:脚本需要以管理员(Windows)或root(Linux/macOS)权限运行,否则无法修改ACL和删除系统文件夹
- 验证ACL:迁移完成后,手动抽查几个文件夹的权限,确保冗余文件夹的权限已正确合并到标准文件夹
- 特殊情况处理:如果标准命名的文件夹不存在,脚本会跳过迁移,需提前确认数据库导出的正确名称已在目录中存在
- 符号链接防护:如果目录包含符号链接,需在代码中添加判断逻辑,避免误删或迁移错误的链接
内容的提问来源于stack exchange,提问作者LearneR
相关产品推荐
相关产品推荐

