【问题标题】:How to use os.umask() in Python如何在 Python 中使用 os.umask()
【发布时间】:2012-05-04 16:32:56
【问题描述】:

我正在尝试使用 os 模块设置 umask。请注意,我在 ~/.profile 中设置的正常 umask 是 umask 0027。

在 bash shell 中,

umask 0022

将允许创建具有权限的文件

-rw-r--r--

但是,当我们导入 os 模块并这样做时:

os.umask(0022)
[do some other code here that creates a file]

我获得了权限

----------

首先,如何让 os.umask(mask) 在 shell 中表现得像 umask?

二、两者区别的逻辑是什么?

注意:我尝试将 0022 转换为十进制,以防它期望小数:

os.umask(18)

但它授予了权限

-----w--w-

还请注意,我试过了

os.umask(00022)

os.mask(0o0022)

这也不起作用。

【问题讨论】:

  • 文件是否可能已经存在?在这种情况下,您将需要使用 chmod
  • @gnibbler:不,它之前被删除了,但这是个好主意。
  • @Ignacio Vazquez-Abrams:尝试先在 shell 中设置 umask 0027,然后运行脚本或调用您的解释器。
  • @Ignacio Vazquez-Abrams:你说得对,我也不能使用与我的代码分开的简单测试 python 程序。奇怪,因为我使用的是相同的技术。
  • 使用old_mask = os.umask(0o000) 然后os.makedirs(./foo/bar) 按预期创建带有777 的目录。而oct(old_mask) 给出的022 是正确的(Unix 上的默认 umask)。

标签: python linux umask


【解决方案1】:

您可能需要向我们展示构成的代码:

[do some other code here that creates a file]

您的代码在我的系统上运行良好:

import os
oldmask = os.umask (022)
fh1 = os.open ("qq1.junk", os.O_CREAT, 0777)
fh2 = os.open ("qq2.junk", os.O_CREAT, 0022)
os.umask (oldmask)
os.close (fh1)
os.close (fh2)

生成文件如下:

-rwxr-xr-x 1 pax pax 0 Apr 24 11:11 qq1.junk
---------- 1 pax pax 0 Apr 24 11:11 qq2.junk

您还应该注意旧的umask 值的恢复,这可以最大限度地减少更改它对本地操作的影响。

从上面的结果可以看出,您还需要注意 umask 值是从您用于创建文件的模式中“减去”的,我们不知道该模式是什么你的特殊情况。

即使在您的 bash 样本中也很明显,因为在创建模式为 777 的文件时,umask 的值 022 将导致 r-xr-xr-x,而不是您所拥有的 rw-r--r--


根据您在下面表明您使用 open 而不是 os.open 的 cmets,粗略浏览一下 Python 源代码似乎表明这转换为使用 0666 的 C fopen 调用初始模式。稍作修改的代码支持这一点:

import os
oldmask = os.umask (022)
fh3 = open ("qq3.junk", "w")
os.umask (0)
fh4 = open ("qq4.junk", "w")
os.umask (oldmask)
fh3.close()
fh4.close()

这给了我们:

-rw-r--r-- 1 pax pax 0 Apr 24 11:44 qq3.junk
-rw-rw-rw- 1 pax pax 0 Apr 24 11:44 qq4.junk

所以我不完全确定您为什么会获得 0000 权限。

当您在您的环境中运行上述程序时,看看结果如何是值得的。如果和我得到的一样,那么问题很可能出在其他地方。

【讨论】:

  • 我在 bash shell 中做了,umask 0022 然后做了 touch /tmp/test 然后做了 ls -l /tmp/test 他们直接在上面复制并粘贴了权限。我认为您混淆了创建文件(假定不需要执行)和创建目录(假定需要执行权限)之间的区别。
  • @narnie,这完全取决于创建文件的代码。显然touchld 在其使用的模式方面有不同的规则。我只是说文件的权限取决于umask模式,而缺少的代码就是告诉我们模式的位。
  • 我用来生成文件的代码相当复杂,因为我正在传递文件处理程序。无论 .profile umask 可能设置为什么,我都希望 umask 为 0022(我的设置为 0027)。要点是我只是在做 f = open(filename, 'w') 然后将文件对象传递给一个控制整体对象的类,该对象具有使用 f 对象写出对象的写入方法,返回,运行 f.close() 的位置。
  • @paxdiable,我认为您已经解决了问题所在。大多数用户的 umask 默认为 0022。我希望我的代码能够在代码中处理不同的 umask 场景。我喜欢将我的 umask 设置为只能由我和我的主要组读取,而不能由任何其他系统用户读取。但是,也可能是 open(filename, 'w') 不关心系统 umask 是什么。我现在确定希望 python 处理这个。
  • @narnie,我认为在较低级别,Python 只是为此调用 fopen 并且应该使用 0666 模式(在 umask 减法之前)。这不能解释为什么你会得到 0000。这可能是因为它会更容易使用 os.open(而不是 open)与特定的 0777 模式和任何你想要的 umask。
【解决方案2】:

挑剔/小心,并且兼容 Python 3k,这是我略有不同的答案(仍然不能解释 OP 的原始问题是什么):

old_umask = os.umask(0o022) # u=rwx,g=rx,o=rx
try:
    # do stuff

finally:
    os.umask(old_umask)

【讨论】:

  • 与 2.x 不兼容; 2.x umask 是一个直接的系统调用,需要整数并在八进制上抛出 TypeError。
  • @CraigYounkins 你是对的!我不确定我是从哪里得到的。 :)
【解决方案3】:

我认为是对 umask 的误解。 umask 设置默认的拒绝,而不是默认的permissions。 所以

import os
oldmask = os.umask (0o022)
fh1 = os.open ("qq1.junk", os.O_CREAT, 0o777)
fh2 = os.open ("qq2.junk", os.O_CREAT, 0o022)
os.umask (oldmask)
os.close (fh1)
os.close (fh2)

确实应该产生如下文件:

-rwxr-xr-x 1 pax pax 0 Apr 24 11:11 qq1.junk
---------- 1 pax pax 0 Apr 24 11:11 qq2.junk

umask 022 删除了组和其他人的写访问权限,这正是我们在那里看到的行为。 我发现回到八进制数字所代表的二进制是有帮助的:

 usr grp others 
-rwx rwx rwx is represented in octal as 0777, requested for qq1.junk
-000 010 010 umask of 022 removes any permission where there is a 1
-rwx r-x r-x is the result achieved requesting 0777 with umask of 022

---- -w- -w- is represented in octal as 0022, requested for qq2.junk
-000 010 010 umask of 022 removes any permission where there is a 1
---- --- --- is the result achieved requesting 0022 with umask of 022

程序按照您的要求运行,不一定按照您认为的那样运行。常见的情况,用电脑:-)

【讨论】:

  • umask 022 应该为目录产生755permissions,而不是文件。对于文件,它应该是644。或者换句话说,umask 022 的目录应该是rwxr-xr-x,但文件应该是rw-r--r--
【解决方案4】:

尽管这似乎是一个直接的系统调用,但在这种情况下,您使用的 Python 版本似乎很重要:

似乎 os.open 在 Python 2.x 和 Python 3.x 中处理预先存在的 umask 的方式不同,可能是因为 2.x 更接近操作系统,而 3.x 做了更多的抽象。

https://docs.python.org/2/library/os.html "默认模式为0777(八进制),当前的umask值首先被屏蔽掉。"

https://docs.python.org/3/library/os.html中没有类似的说法

【讨论】:

    猜你喜欢
    • 2012-07-02
    • 2013-09-17
    • 2019-07-31
    • 2011-01-21
    • 2018-08-27
    • 2018-06-15
    • 2012-12-14
    • 2011-04-24
    • 2010-10-19
    相关资源
    最近更新 更多