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

Python创建目录权限不符求助:设置0o777却获异常权限

问题:Python复制函数创建的目录权限与预期不符

我编写了如下Python复制函数,运行后发现创建的目录权限与显式设置的不一致:

代码实现

import os
import shutil
import stat

def copy(src, dst):
    if not os.path.isdir(os.path.dirname(src)):
        print('No source directory to copy from')
    else:
        if not os.path.isdir(dst):
            print('No destination directory to copy files to')
            print('Creating destination directory')
            os.umask(0o002)
            os.mkdir(dst, mode=0o777)
            print('Destination directory created')
    shutil.copy2(src, dst)
    os.chmod(dst, stat.S_IEXEC)
    os.chmod(dst, stat.S_IXGRP)
    print("copied "+str(src)+" --> "+str(dst))

实际权限输出

# ls -la /tmp/
total 16
drwxrwxr-x  4 userx  userx  4096 Jul 25 10:21 .
drwxrwxrwt 25 root root 4096 Jul 25 10:21 ..
d-----x---  2 userx  userx  4096 Jul 25 10:21 tmpdir

系统默认umask为0022,请问这是什么原因?


原因分析与解决办法

核心原因:错误的os.chmod调用方式

os.chmod的第二个参数是完整的权限掩码,不是追加权限位。你的代码中两次调用os.chmod:

  • 第一次os.chmod(dst, stat.S_IEXEC):将目录权限直接设置为仅所有者可执行(对应权限位0o100)
  • 第二次os.chmod(dst, stat.S_IXGRP):将权限覆盖为仅组用户可执行(对应权限位0o010)

最终目录权限变为0o010,对应ls显示的d-----x---(所有者无任何权限,组用户仅可执行,其他用户无权限),完全覆盖了mkdir时设置的权限。

次要问题:umask的全局影响

你调用os.umask(0o002)修改了进程的全局umask,这会影响后续所有文件/目录的创建操作,且未恢复原umask值(系统默认是0o022),可能导致其他操作的权限不符合预期。正确的做法是修改后立即恢复原umask:

old_umask = os.umask(0o002)
try:
    os.mkdir(dst, mode=0o777)
finally:
    os.umask(old_umask)

解决办法

  1. 一次性设置完整权限:如果要给目录设置775权限(对应umask002),直接调用一次os.chmod:
    os.chmod(dst, 0o775)
    
    或者要保留原权限并添加执行权限,用按位或操作:
    current_mode = os.stat(dst).st_mode
    os.chmod(dst, current_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IRWXU | stat.S_IRWXG)
    
  2. 调整代码逻辑:将目录权限设置放在mkdir之后,避免后续错误覆盖:
    修改后的代码片段:
    if not os.path.isdir(dst):
        print('No destination directory to copy files to')
        print('Creating destination directory')
        old_umask = os.umask(0o002)
        try:
            os.mkdir(dst, mode=0o777)
        finally:
            os.umask(old_umask)
        print('Destination directory created')
        # 直接设置正确的目录权限
        os.chmod(dst, 0o775)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:48:28