如何在 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 中获取默认文件权限?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取权限删除文件?

如何设置UNIX/Linux中新创建目录或文件的默认权限

WIN7系统下删除文件,出来需要管理员权限才能删除该怎么删除文件

使用python检查文件夹/文件ntfs权限

Android 11及以上授予文件管理权限

解决Docker以默认root用户运行生成的文件权限为root的问题