当模式被忽略时,如何最佳使用os.makedirs()

0 投票
1 回答
1983 浏览
提问于 2025-04-16 19:24

在我正在使用的一个Linux服务器上,我需要创建以下结构的文件夹:

/dir1/dir2/dir3/YYYY/MM/DD/file.ext

由于这些文件夹是根据日期来决定的,有时候我需要一次性创建多个文件夹,比如.../2011/01/01/,而且它们都需要权限设置为0o2755。

当我在服务器上使用os.makedirs(dir, mode=0o2755)时,它会正确设置权限中的0o755部分,但却忽略了SGID(2)位。我猜这可能是因为os.makedirs在某些系统上会忽略权限,文档中也有提到。我看到其他人也遇到过umask和os.makedirs()的问题,但我尝试过调整umask(我设置为0002,也试过0000),结果还是忽略了SGID位。

我为此问题写了一个函数,解决方案如下:

def special_makedirs(base_dir, target_dir, mode=0o2755):
    base_dir = os.path.abspath(base_dir)
    target_dir = os.path.abspath(target_dir)
    if os.path.commonprefix([base_dir, target_dir]) != base_dir:
        log.error("Target directory %s is not a subdirectory of %s" %(target_dir, base_dir))
        raise ValueError("Target directory %s is not a subdirectory of %s" % (target_dir, base_dir))

    # Create initial directory
    os.makedirs(target_dir, mode=mode)

    # Verify permissions
    temp = target_dir
    while temp != base_dir and stat.S_IMODE(os.stat(temp)) != mode:
        os.chmod(temp, mode)
        temp = os.path.split(temp)[0]

现在我知道这个函数可能不能解决所有情况,但我只会用它来满足我自己的特定需求。

所以,我有几个问题:

  1. 我是不是误解了os.makedirs的文档,认为它在某些系统上会忽略权限?其他人也遇到过这个问题吗?

  2. 我的函数看起来是解决这个问题的最有效方法吗?

感谢你们提供的任何建议。如果我的情况不太清楚,我很抱歉。

1 个回答

0

来自mkdir(2)的手册页面:

NOTES
        Under  Linux  apart from the permission bits, only the S_ISVTX mode bit
        is honored.  That is, under Linux the created directory  actually  gets
        mode (mode & ~umask & 01777).

所以,没错,SGID会被忽略。你可以在创建之后再设置它。

撰写回答