On a linux server I’m working on I need to create directories with the following structure:
/dir1/dir2/dir3/YYYY/MM/DD/file.ext
There are certain cases (since the directories depend on the date) that I need to create more than a single directory at a time, such as …/2011/01/01/, all of them needing the permission 0o2755.
When I use os.makedirs(dir, mode=0o2755) on my server it properly sets the 0o755 part of the permission, but ignores the SGID (2) bit. I’m guessing that this is because of os.makedirs ignoring permissions on some systems, as the documentation describes. I’ve read that other people have had problems with umask and os.makedirs(), but I’ve played around with umask (its set to 0002, I’ve tried 0000) and it still ignores the SGID bit.
My solution for this is the following function:
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]
Now I’m sure this doesn’t meet all cases, but I’ll be the only one using this function for my specific need.
So…my questions are:
-
Am I misunderstanding the os.makedirs documentation when it says that it ignores permissions on some systems? Have others had this problem?
-
Does my function seem like the most efficient way to fix this problem?
Thanks for any tips you can give. Sorry if my situation doesn’t make sense.
From the
mkdir(2)man page:So yes, SGID is ignored. Set it after the fact.