如何在保留现有权限的情况下使用os.chmod更改文件权限?

3

我想要一次性地选择性地修改用户、组或其他人的权限,但每当我使用chmod时,所有权限都会被覆盖。


根据chmod文档的建议,我尝试将当前文件权限与新权限进行按位或操作:

例如:

GROUP_RO = S_IRGRP #Group read only
current_permissions = stat.S_IMODE(os.stat(path).st_mode)

os.chmod(path, current_permissions | GROUP_RO)

我也尝试过使用位掩码。但我无法想出一种方法将位掩码组合在一起,以便在修改用户权限时,可以保护/掩盖组和其他权限不被修改。

我尝试按以下方式使用位掩码:

GROUP_RO = S_IRGRP #Group read only
USER_MASK = S_IRWXU

os.chmod(path, USER_MASK | GROUP_RO) #this works at preventing User permissions from being modified

但将多个掩码连接起来是不行的:

USER_MASK = S_IRWXU
OTHERS_MASK = S_IRWXO

os.chmod(path, USER_MASK | OTHERS_MASK | GROUP_RO) #does not work

我尝试了无数不同的位运算符、位掩码,有时加上当前权限,但都没有成功。


我想要做的是:

# current permissions -> U: read only, G: read and write, O: write only
os.chmod(path, [whatever code making this work])
# new permissions -> U: read only, G: read only, O: write only

在任何情况下,其他实体不会被修改。

你展示的例子语法无效。你能否展示一个有效的例子,并说明你尝试过使用哪些掩码? - Mad Physicist
@MadPhysicist 是个打字错误。我已经修正了,并添加了我尝试过的其他解决方案的示例。 - dandev
1个回答

2
你的所有尝试都非常接近。问题在于,| 运算符无法关闭位。因此,当你执行 current_permissions | S_IRGRP 时,你正在设置正确的位,但你并没有关闭写权限。
要关闭位,你需要使用 &。有几种好的方法可以做到这一点。
我选择的方法可能是取消所有组权限,并将它们设置为所需的值:
(current_permissions & ~S_IRWXG) | S_IRGRP

第一部分取消所有组权限,第二部分像以前一样应用只读模式。
另一种方法是禁用除用户和其他部分之外的所有内容,然后设置组:
(current_permissions & (S_IRWXU | S_IRWXO)) | S_IRGRP

两者通常是等价的,除非您在权限中设置了一些奇怪的位。

这个公式本质上是我可以使用的公式,用于独立修改用户、组或其他人的权限吗?-> os.chmod((CURRENT_PERMS&〜MASK_OF_ENTITY_TO_BE_MOTIFIED)| NEW_PERMS_OF_ENTITY_TO_BE_MOTIFIED)。我需要更多地阅读您的答案和os.stat,以了解您的意思以及位的情况。 - dandev
@Dante。是的,你有一个大致的想法。解决方案像你说的那样是通用的。理解按位取反~、按位与&和按位或|的作用,它就会变得非常清晰。 - Mad Physicist
我回答了自己的评论 - 我刚刚测试了一下 - 这太棒了。谢谢,我也很感激你的解释,这对我除了chmod之外也有很大帮助。 - dandev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接