在 Windows 中,"os.chmod" 在 Python 中无法正常工作
In Windows, "os.chmod" in Python not working properly
我尝试在 Windows 中 Python 中设置文件访问权限 Windows。
我可以成功移除写入权限,但不能成功移除读取权限:
>>> 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'
最后一行应该引发错误,因为该文件应该没有读取权限。
如何解决问题?
在 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()
我尝试在 Windows 中 Python 中设置文件访问权限 Windows。
我可以成功移除写入权限,但不能成功移除读取权限:
>>> 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'
最后一行应该引发错误,因为该文件应该没有读取权限。
如何解决问题?
在 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()