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)
解决办法
- 一次性设置完整权限:如果要给目录设置
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) - 调整代码逻辑:将目录权限设置放在
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
相关产品推荐
相关产品推荐

