如何在 Python 中获取默认文件权限?
Posted
技术标签:
【中文标题】如何在 Python 中获取默认文件权限?【英文标题】:How can I get the default file permissions in Python? 【发布时间】:2011-11-01 07:47:00 【问题描述】:我正在编写一个 Python 脚本,在该脚本中我将输出写入一个临时文件,然后在完成并关闭该文件后将该文件移动到其最终目的地。脚本完成后,我希望输出文件具有与通过open(filename,"w")
正常创建的权限相同的权限。实际上,该文件将具有 tempfile 模块用于临时文件的一组限制性权限。
如果我在适当位置创建输出文件,我有没有办法弄清楚输出文件的“默认”文件权限是什么,以便在移动临时文件之前将它们应用到临时文件?
【问题讨论】:
看看这个:***.com/questions/1861836/… @vettipayyan:这个问题与这个问题无关。 【参考方案1】:记录一下,我遇到了类似的问题,这是我使用的代码:
import os
from tempfile import NamedTemporaryFile
def UmaskNamedTemporaryFile(*args, **kargs):
fdesc = NamedTemporaryFile(*args, **kargs)
# we need to set umask to get its current value. As noted
# by Florian Brucker (comment), this is a potential security
# issue, as it affects all the threads. Considering that it is
# less a problem to create a file with permissions 000 than 666,
# we use 666 as the umask temporary value.
umask = os.umask(0o666)
os.umask(umask)
os.chmod(fdesc.name, 0o666 & ~umask)
return fdesc
【讨论】:
使用os.umask(0)
是一个潜在的安全问题,请参阅bugs.python.org/issue21082。
谢谢!我不知道这个问题(我感到羞耻)。我已经更新了答案。你还好吗?
我自己不确定最佳方法,但至少这不会留下全局可写文件的风险。感谢您更新您的答案,没有理由感到羞耻:您的原始答案基本上是每个人都推荐的,而我也刚刚了解了这个问题。【参考方案2】:
有一个函数umask
in the os
模块。您无法获取当前的 umask 本身,您必须设置它并且函数返回之前的设置。
umask 继承自父进程。它描述了在创建文件或目录时不设置哪些位。
【讨论】:
那么,我是否应该使用任何值调用os.umask
一次,保存返回值,然后使用该值再次调用它以恢复它,然后从该掩码中获取适当的权限?
为什么您只对 umask 是 的内容感兴趣,而不对它应该是什么 感兴趣?
您确定要使用tempfile
吗?
嗯,tempfile 模块的优点是它为您提供了一个保证不存在的文件名。
@hop 这是一个合法的任务。例如,在安全方面,可能需要检查 umask 是否过于宽松。任务本身可能不是修复弱 umask,而是报告它。静默修复它可以掩盖用户在锁定系统上有意/无意共享文件的问题。【参考方案3】:
这种方式速度慢但安全,适用于任何具有 'umask' shell 命令的系统:
def current_umask() -> int:
"""Makes a best attempt to determine the current umask value of the calling process in a safe way.
Unfortunately, os.umask() is not threadsafe and poses a security risk, since there is no way to read
the current umask without temporarily setting it to a new value, then restoring it, which will affect
permissions on files created by other threads in this process during the time the umask is changed.
On recent linux kernels (>= 4.1), the current umask can be read from /proc/self/status.
On older systems, the safest way is to spawn a shell and execute the 'umask' command. The shell will
inherit the current process's umask, and will use the unsafe call, but it does so in a separate,
single-threaded process, which makes it safe.
Returns:
int: The current process's umask value
"""
mask: Optional[int] = None
try:
with open('/proc/self/status') as fd:
for line in fd:
if line.startswith('Umask:'):
mask = int(line[6:].strip(), 8)
break
except FileNotFoundError:
pass
except ValueError:
pass
if mask is None:
import subprocess
mask = int(subprocess.check_output('umask', shell=True).decode('utf-8').strip(), 8)
return mask
【讨论】:
【参考方案4】:import os
def current_umask() -> int:
tmp = os.umask(0o022)
os.umask(tmp)
return tmp
此功能在一些 python 包中实现,例如pip 和 setuptools。
【讨论】:
以上是关于如何在 Python 中获取默认文件权限?的主要内容,如果未能解决你的问题,请参考以下文章