【问题标题】:In Windows, "os.chmod" in Python not working properly在 Windows 中,Python 中的“os.chmod”无法正常工作
【发布时间】:2021-02-10 04:21:12
【问题描述】:

我尝试在 Windows 中的 os.chmod 中设置 Python 中的文件访问权限。

我可以成功删除写访问权限,但不能成功删除读访问权限:

>>> import os

>>> import stat

>>> from pathlib import Path

>>> toto = Path("toto.txt")

>>> toto.write_text("Hello")
5


>>> toto.read_text()
'Hello'


>>> os.chmod(toto, toto.stat().st_mode & ~stat.S_IWUSR)

>>> toto.write_text("Hello")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\python37-32\lib\pathlib.py", line 1208, in write_text
    with self.open(mode='w', encoding=encoding, errors=errors) as f:
  File "c:\python37-32\lib\pathlib.py", line 1176, in open
    opener=self._opener)
  File "c:\python37-32\lib\pathlib.py", line 1030, in _opener
    return self._accessor.open(self, flags, mode)
PermissionError: [Errno 13] Permission denied: 'toto.txt'

[Errno 13] Permission denied: 'toto.txt'

>>> os.chmod(toto, stat.S_IRWXU)

>>> toto.write_text("Hello")
5


>>> os.chmod(toto, toto.stat().st_mode & ~stat.S_IRUSR)

>>> toto.read_text()
'Hello'

最后一行应该引发了错误,因为该文件应该没有被读取的权限。

如何解决这个问题?

【问题讨论】:

    标签: python windows chmod


    【解决方案1】:

    在 Windows 中设置访问权限的最佳方法是使用icacls

    这段代码可以帮助解决这个问题:

    """
    Example of script to modify access rights with "icacls" in Windows
    """
    from contextlib import contextmanager
    from enum import Enum
    from subprocess import check_output
    from pathlib import Path
    from typing import Generator, List
    
    
    class AccessRight(Enum):
        """Access Rights for files/folders"""
    
        DELETE = "D"
        FULL = "F"  # Edit Permissions + Create + Delete + Read + Write
        NO_ACCESS = "N"
        MODIFY = "M"  # Create + Delete + Read + Write
        READ_EXECUTE = "RX"
        READ_ONLY = "R"
        WRITE_ONLY = "W"
    
    
    def change_access_rights(file: Path, access: AccessRight) -> None:
        """Change Access Rights of a given file"""
    
        def cmd(access_right: AccessRight, mode="grant:r") -> List[str]:
            return [
                "icacls",
                str(file),
                "/inheritance:r",
                f"/{mode}",
                f"Everyone:{access_right.value}",
            ]
    
        if access == AccessRight.NO_ACCESS:
            check_output(cmd(AccessRight.FULL, mode="deny"))
        else:
            check_output(cmd(access))
    
    
    @contextmanager
    def set_access_right(file: Path, access: AccessRight) -> Generator[Path, None, None]:
        """Context Manager to temporarily set a given access rights to a file and reset"""
    
        try:
            change_access_rights(file, access)
            yield file
    
        finally:
            change_access_rights(file, AccessRight.FULL)
    
    
    # We create a file (if it does not exist) with empty content
    toto = Path("toto.txt")
    toto.touch()
    
    # We temporarily set access rights of the
    with set_access_right(toto, AccessRight.WRITE_ONLY) as path:
        path.write_text("My name is Toto")
        try:
            content = path.read_text()
            print(f":( Should not be able to read content of file but read: {content}")
        except PermissionError:
            print("Cannot read toto: YEAH!")
    
    # We check that access rights have been restored
    print(path.read_text())
    
    change_access_rights(toto, AccessRight.NO_ACCESS)
    try:
        toto.write_text("My name is Toto")
        print(f":( Should not be able to write in file")
    except PermissionError:
        print("NO ACCESS to toto: YEAH!")
    
    # We check that access rights have been restored (and delete the file to stay clean)
    change_access_rights(toto, AccessRight.FULL)
    toto.write_text("The end...")
    print(toto.read_text())
    
    change_access_rights(toto, AccessRight.DELETE)
    toto.unlink()
    

    【讨论】:

      猜你喜欢
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-23
      • 2020-08-23
      相关资源
      最近更新 更多