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

如何在Python中一次性修改嵌套目录的权限?

问题

我目前通过以下代码逐个修改嵌套目录(例如路径/apps/sys/utils/prod/sales/apparel/)的权限。请问能否一次性完成权限修改,达到与循环逐个修改相同的效果?

import os
import stat
def change_permissions(path, new_mode):
    """Change permissions of the directory to new_mode."""
    if not os.path.islink(path):
        original_mode = os.stat(path).st_mode
        os.chmod(path, new_mode)
        oct_perm = oct(new_mode)
        unix_perm = oct_perm[-3: (len(oct_perm))]
        print(f"Permission of {path} changed to {new_mode} = {unix_perm}")
        return original_mode
    return None


target_full_path = "/apps/sys/utils/prod/sales/apparel/shirts.csv"
# Determine the directory path up to which permissions need to be changed
target_dir = os.path.dirname(target_full_path)
print(f"The abstract file dir path upto which perm to be changed {target_dir}")
# Change permissions for the specific directory needed
original_permissions = []
current_dir = "/apps/sys/utils/prod"
for part in target_dir.split(os.sep)[len(dest_root.split(os.sep)):]:
    current_dir = os.path.join(current_dir, part)
    print(f"\n### part = {part} and current_dir = {current_dir}")
    if not os.path.exists(current_dir):
        os.makedirs(current_dir)
        print(f"Created the current_dir = {current_dir}")
    original_mode = change_permissions(current_dir, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
    original_permissions.append((current_dir, original_mode))
    print (f"Original mode for current_dir ({current_dir}) is {original_mode}\n")
回答

可以一次性完成权限修改,以下是两种实现方式,效果和你当前的循环逻辑完全一致:

方式一:用os.walk反向遍历目录层级

os.walk可以遍历目录树,反向遍历就能从最深层的子目录往上处理,一次性完成所有目标目录的权限修改,同时保留原权限记录:

import os
import stat

def change_permissions(path, new_mode):
    """Change permissions of the directory to new_mode."""
    if not os.path.islink(path):
        original_mode = os.stat(path).st_mode
        os.chmod(path, new_mode)
        oct_perm = oct(new_mode)
        unix_perm = oct_perm[-3:]
        print(f"Permission of {path} changed to {new_mode} = {unix_perm}")
        return original_mode
    return None

target_full_path = "/apps/sys/utils/prod/sales/apparel/shirts.csv"
target_dir = os.path.dirname(target_full_path)
current_root = "/apps/sys/utils/prod"

original_permissions = []

# 反向遍历目录树,从最底层子目录开始处理
for root, dirs, files in os.walk(current_root, topdown=False):
    # 只处理current_root到target_dir之间的目录
    if root.startswith(target_dir) and root != current_root:
        print(f"\n### Processing directory: {root}")
        original_mode = change_permissions(root, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
        original_permissions.append((root, original_mode))
        print(f"Original mode for {root} is {original_mode}\n")

# 额外处理target_dir本身(确保覆盖到最终目录)
if target_dir not in [item[0] for item in original_permissions]:
    print(f"\n### Processing directory: {target_dir}")
    original_mode = change_permissions(target_dir, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
    original_permissions.append((target_dir, original_mode))
    print(f"Original mode for {target_dir} is {original_mode}\n")

方式二:创建目录时直接指定权限(针对新建目录场景)

如果你的代码中很多目录是通过os.makedirs新建的,可以直接在创建时指定权限,避免后续逐个修改:

import os
import stat

def change_permissions(path, new_mode):
    """Change permissions of the directory to new_mode."""
    if not os.path.islink(path):
        original_mode = os.stat(path).st_mode
        os.chmod(path, new_mode)
        oct_perm = oct(new_mode)
        unix_perm = oct_perm[-3:]
        print(f"Permission of {path} changed to {new_mode} = {unix_perm}")
        return original_mode
    return None

target_full_path = "/apps/sys/utils/prod/sales/apparel/shirts.csv"
target_dir = os.path.dirname(target_full_path)
current_root = "/apps/sys/utils/prod"

original_permissions = []

# 新建目录时直接指定权限,0o777对应stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO
if not os.path.exists(target_dir):
    os.makedirs(target_dir, mode=0o777, exist_ok=True)
    print(f"Created directory tree: {target_dir} with permissions 0o777")

# 处理已存在的目录(如果有的话)
for root, dirs, files in os.walk(current_root, topdown=False):
    if root.startswith(target_dir) and root != current_root:
        print(f"\n### Processing existing directory: {root}")
        original_mode = change_permissions(root, 0o777)
        original_permissions.append((root, original_mode))
        print(f"Original mode for {root} is {original_mode}\n")

注意事项

  • 两种方式都会保留原权限的记录,和你原代码的original_permissions列表功能一致
  • 如果目录是符号链接,都会跳过处理,和原逻辑对齐
  • 方式一适合处理已存在的目录树,方式二更适合需要新建目录的场景

内容的提问来源于stack exchange,提问作者A.G.Progm.Enthusiast

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:12:43