在Python中更改文件权限

Abu*_*nat 52 python file-permissions

我正在尝试更改文件访问权限:

os.chmod(path, mode)
Run Code Online (Sandbox Code Playgroud)

我想把它变为只读:

os.chmod(path, 0444)
Run Code Online (Sandbox Code Playgroud)

有没有其他方法使文件只读?

Joh*_*ooy 66

os.chmod(path, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
Run Code Online (Sandbox Code Playgroud)

统计

以下标志也可以在os.chmod()的mode参数中使用:

stat.S_ISUID 设置UID位.

stat.S_ISGIDSet-group-ID位.这个位有几个特殊用途.对于目录,它指示将BSD语义用于该目录:在那里创建的文件从目录继承其组ID,而不是从创建进程的有效组ID继承,并且在那里创建的目录也将设置S_ISGID位.对于未设置组执行位(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_ENFMTSystem 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或0444为0444,而加法会产生不同且错误的值) ). (6认同)
  • @Shule` |`在组合来自两个位掩码的位时更合适.但是,如果每个掩码只有一个单独的位设置,就像上面答案中的所有常量一样,那么`+`是等价的. (2认同)

Inb*_*ose 30

os.chmod(path, 0444) 用于在Python 2.x中更改文件权限的Python命令.对于组合的Python 2和Python 3解决方案,请更改04440o444.

您总是可以使用Python来调用chmod命令subprocess.我认为这只适用于Linux.

import subprocess

subprocess.call(['chmod', '0444', 'path'])
Run Code Online (Sandbox Code Playgroud)

  • 没关系我的评论!对不起Inbar Rose.你没事.显然,0444在Python 2.x中运行良好.但是,它会在Python 3.x中导致SyntaxError.要修复它,只需在Python 3.x中执行0o444. (3认同)
  • os.chmod 可能是正确的函数,但是 0444(在 `os.chmod(path, 0444)` 中)作为 int 将导致 SyntaxError(由于前导 0),并且在字符串形式中它不会给出想要的效果。您必须将数字转换为该方法使用的数字系统,这是不一样的。也许你知道,但其他人可能不知道。 (2认同)

Git*_*ero 16

只需在八进制中包含权限整数(适用于python 2和python3):

os.chmod(path, 0o444)
Run Code Online (Sandbox Code Playgroud)


Chi*_*ogg 15

所有当前的答案都破坏了非写入权限:它们使文件对每个人都可读但不可执行.当然,这是因为最初的问题要求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)
Run Code Online (Sandbox Code Playgroud)

为什么这样做?

正如John La Rooy所指出的,stat.S_IWUSR基本上意味着"用户写入权限的位掩码".我们希望将相应的权限位设置为0.为此,我们需要完全相反的位掩码(即,在该位置具有0,在其他地方为1).~翻转所有位的运算符给出了我们的确切结果.如果我们通过"按位和"运算符(&)将它应用于任何变量,它将把相应的位清零.

我们需要用"group"和"other"权限位重复这个逻辑.在这里,我们可以节省一些时间,只需将&它们放在一起(形成NO_WRITING位恒定).

最后一步是获取当前文件的权限,并实际执行按位和操作.


She*_*ohn 6

仅供参考,这里是一个将 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
Run Code Online (Sandbox Code Playgroud)

请注意,设置 SUID/SGID/SVTX 位将自动设置相应的执行位。如果没有这个,所得到的权限将是无效的(ST字符)。


Meg*_*iya 6

只需在权限编号前添加 0:
例如 - 我们要授予所有权限 - 777
语法: os.chmod("file_name" , permission)

import os
os.chmod("file_name" , 0777)
Run Code Online (Sandbox Code Playgroud)

Python 3.7 版不支持此语法。它需要八进制文字的“0o”前缀 - 这是我在 PyCharm 中得到的评论

所以对于python 3.7,它将是

import os
os.chmod("file_name" , 0o777)
Run Code Online (Sandbox Code Playgroud)


Sup*_*ova 5

你也可以使用pathlib

from pathlib import Path

fl = Path("file_name")

fl.chmod(0o444)
Run Code Online (Sandbox Code Playgroud)