python3 os.mkdir()不强制执行正确的模式

时间:2016-05-09 14:36:35

标签: python-3.x mkdir

是错误还是功能?

当我使用os.mkdir(带有pathlib.Path.mkdir的同义词)和显式模式创建目录时,创建的目录的权限不适合。如果我再次强制执行os.chmod,则可以...

>>> import sys, os
>>> sys.version
'3.4.3 (default, Feb 27 2015, 18:13:37) \n[GCC 4.4.5]'
>>> os.mkdir('truite', mode=0o2770)
>>> oct(os.stat('truite').st_mode)
'0o40750'
>>> os.chmod('truite', 0o2770)
>>> oct(os.stat('truite').st_mode)
'0o42770'

因为我希望能够使用父级和模式o2770创建一个目录,所以这里是代码(pthpathlib.Path对象):

def make_shared_dir(pth) :
    if not pth.parent.is_dir() :
        make_shared_dir(pth.parent)
    if not pth.is_dir() :
        pth.mkdir()
    pth.chmod(0o2770)   

1 个答案:

答案 0 :(得分:4)

这是一个功能。

documentation提到了它,虽然是短暂的:

  

os.mkdir(path[, mode])

     

使用数字模式模式创建名为path的目录。默认模式为0777(八进制)。在某些系统上,模式被忽略。 在使用它的地方,首先屏蔽当前的umask值。

umask是一个按进程设置,用于限制应用于所有新创建的文件/目录的权限。

umask是一个数字(通常以八进制显示),就像权限本身一样,但在结果权限中,umask中设置的任何位都是禁止。例如,如果您的umask是0o022(一个常见的默认值),则新创建的文件/目录将不会具有组或世界写入权限。

新创建的文件/目录的权限也始终限制为最后三个八进制数字(即0o777)。因此,如果你的umask是0o022,那么一切都表现得像0o7022一样。 这就是你的setgid位也被删除的原因。

顺便说一句,这不是Python的事情;这是一个Unix的事情。它不仅适用于Python,而且适用于Ubuntu中的所有程序。您可以在终端中输入umask命令来检查当前的umask。事实上,当Linux内核执行Python(以及其他所有程序)调用以创建目录的mkdir()系统调用时,umask会强制执行。

您可以在the documentation for mkdir()man 2 mkdir

中自行查看
  

参数 mode 指定要使用的权限。它以通常的方式由进程的 umask 修改:创建的目录的权限是( mode &〜 umask & 0777)

原因当然是安全性。使用umask,用户可以对默认权限进行大量控制(例如,阻止对世界甚至群组的默认读取权限)。如果你想要粘贴,setuid,setgid,group-writable或world-writable(假设是0o022 umask)的文件,你需要使用chmod显式地执行此操作。