我正在尝试更改文件访问权限:
os.chmod(path, mode)
我想将其设为只读:
os.chmod(path, 0444)
还有其他方法可以将文件设为只读吗?
我正在尝试更改文件访问权限:
os.chmod(path, mode)
我想将其设为只读:
os.chmod(path, 0444)
还有其他方法可以将文件设为只读吗?
Answers:
os.chmod(path, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
下列标志也可以在os.chmod()的mode参数中使用:
stat.S_ISUID
设置UID位。
stat.S_ISGID
设置组ID位。该位有几种特殊用途。对于目录,它指示该目录将使用BSD语义:在该目录中创建的文件将从该目录继承其组ID,而不是从创建过程的有效组ID继承它们,并且在该目录中创建的目录还将获得S_ISGID位置1。对于未设置组执行位(S_IXGRP)的文件,set-group-ID位表示强制性文件/记录锁定(另请参见S_ENFMT)。
stat.S_ISVTX
粘性位。在目录上设置此位时,意味着该目录中的文件只能由文件的所有者,目录的所有者或特权进程重命名或删除。
stat.S_IRWXU
文件所有者权限的掩码。
stat.S_IRUSR
所有者拥有阅读权限。
stat.S_IWUSR
所有者具有写权限。
stat.S_IXUSR
所有者具有执行权限。
stat.S_IRWXG
组权限的掩码。
stat.S_IRGRP
群组拥有读取权限。
stat.S_IWGRP
组具有写权限。
stat.S_IXGRP
组具有执行权限。
stat.S_IRWXO
屏蔽其他人(不在组中)的权限。
stat.S_IROTH
其他人具有阅读权限。
stat.S_IWOTH
其他人具有写权限。
stat.S_IXOTH
其他人具有执行权限。
stat.S_ENFMT
System V文件锁定实施。该标志与S_ISGID共享:未设置组执行位(S_IXGRP)的文件将强制执行文件/记录锁定。
stat.S_IREAD
Unix V7的S_IRUSR同义词。
stat.S_IWRITE
Unix V7的S_IWUSR同义词。
stat.S_IEXEC
Unix V7的S_IXUSR同义词。
stat
只是方便人类阅读的糖。S_IRUSR
是0400,S_IRGRP
是040,S_IROTH
是4;将它们与按位OR组合会产生0444。您可以改为将它们相加,但在一般情况下,OR是正确的,因为即使有重叠的位(0444 OR 0444为0444,它也可以工作,而相加会产生不同且错误的值)。
+
似乎也可以代替|
。我不知道是否有理由在另一个之上使用一个。
|
当组合来自两个位掩码的位时,@ Shule更合适。但是,如果每个掩码只有一个单独的,单独的位集(如上述答案中的所有常量),则+
是等效的。
+
操纵预先存在的模式时,您必须小心机智。如果已经设置了模式,+
则将无法使用,但|
可以。例如,mode = stat.S_IWUSR + stat.S_IRUSR; ... some code ...; mode = mode + stat.S_IWUSR;
将无法使用,但最后一个命令将与一起使用|
。
os.chmod(path, 0444)
是用于在Python 2.x中更改文件权限的Python命令。对于Python 2和Python 3的组合解决方案,请更改0444
为0o444
。
您始终可以使用Python使用来调用chmod命令subprocess
。我认为这仅适用于Linux。
import subprocess
subprocess.call(['chmod', '0444', 'path'])
os.chmod(path, 0444)
)作为int会引起SyntaxError(由于前导0),并且以字符串形式不会产生预期的效果。您必须将数字转换为该方法使用的数字系统,这是不一样的。也许您知道,但是其他人可能不知道。
只需在八进制中包含权限整数(适用于python 2和python3):
os.chmod(path, 0o444)
当前所有答案都破坏了非写权限:它们使文件对所有人可读,但不能执行。当然,这是因为最初的问题要求获得444
权限-但是我们可以做得更好!
这是一个解决方案,不影响所有单独的“读取”和“执行”位。我编写了冗长的代码以使其易于理解。如果愿意,可以使其更简洁。
import os
import stat
def remove_write_permissions(path):
"""Remove write permissions from this path, while keeping all other permissions intact.
Params:
path: The path whose permissions to alter.
"""
NO_USER_WRITING = ~stat.S_IWUSR
NO_GROUP_WRITING = ~stat.S_IWGRP
NO_OTHER_WRITING = ~stat.S_IWOTH
NO_WRITING = NO_USER_WRITING & NO_GROUP_WRITING & NO_OTHER_WRITING
current_permissions = stat.S_IMODE(os.lstat(path).st_mode)
os.chmod(path, current_permissions & NO_WRITING)
为什么这样做?
正如John La Rooy指出的那样,stat.S_IWUSR
基本上是指“用户写权限的位掩码”。我们希望将相应的权限位设置为0。为此,我们需要完全相反的位掩码(即,该位置的掩码为0,其他位置均为1)。~
翻转所有位的运算符将为我们提供确切的信息。如果我们通过“按位与”运算符(&
)将其应用于任何变量,则它将相应位清零。
我们还需要使用“组”和“其他”权限位重复此逻辑。在这里,我们可以&
通过将它们全部在一起(形成NO_WRITING
位常量)来节省一些时间。
最后一步是获取当前文件的权限,并实际执行按位与操作。
无需记住标志。请记住,您可以随时执行以下操作:
subprocess.call(["chmod", "a-w", "file/path])
不可移植,但易于编写和记住:
请参阅man chmod
其他选项和更详细的说明。
os.chmod
Gitano的答案中的建议使用。
仅供参考,此处的功能是将9个字符的权限字符串(例如'rwsr-x-wt')转换为可以与使用的掩码os.chmod()
。
def perm2mask(p):
assert len(p) == 9, 'Bad permission length'
assert all(p[k] in 'rw-' for k in [0,1,3,4,6,7]), 'Bad permission format (read-write)'
assert all(p[k] in 'xs-' for k in [2,5]), 'Bad permission format (execute)'
assert p[8] in 'xt', 'Bad permission format (execute other)'
m = 0
if p[0] == 'r': m |= stat.S_IRUSR
if p[1] == 'w': m |= stat.S_IWUSR
if p[2] == 'x': m |= stat.S_IXUSR
if p[2] == 's': m |= stat.S_IXUSR | stat.S_ISUID
if p[3] == 'r': m |= stat.S_IRGRP
if p[4] == 'w': m |= stat.S_IWGRP
if p[5] == 'x': m |= stat.S_IXGRP
if p[5] == 's': m |= stat.S_IXGRP | stat.S_ISGID
if p[6] == 'r': m |= stat.S_IROTH
if p[7] == 'w': m |= stat.S_IWOTH
if p[8] == 'x': m |= stat.S_IXOTH
if p[8] == 't': m |= stat.S_IXOTH | stat.S_ISVTX
return m
请注意,设置SUID / SGID / SVTX位将自动设置相应的执行位。如果没有此权限,则产生的权限将无效(ST
字符)。