Issue
In python 2.7, I save data to a path, e.g. A/B/C/data.txt
:
import os
file_path = 'A/B/C/data.txt'
# create directory A/B/C
dir_name = os.path.dirname(file_path)
if not os.path.exists(dir_name):
os.makedirs(dirp_name)
# save data to file
with open(file_path, 'w') as f:
json.dump(data, f)
# change file permission mode to be 0x666
os.chmod(file_path, 0666)
The permission mode of file data.txt
has been changed. But however, this code doesn't change the permission mode of directories A/B/C
along the path. I want to set permission mode of directories, too.
os.chmod('A', 0666)
os.chmod('A/B', 0666)
os.chmod('A/B/C', 0666)
Is there an elegant way of doing this?
Thanks!
Solution
os.mkdir(path[, mode])
allows setting permission mode when we create a directory. The default mode is 0777 (octal). If the directory already exists, OSError is raised.
Solution 1:
# RW only permission mode is 0666 in python 2 and 0o666 in python 3
RW_only = 0666
# create directory A/B/C
dir_name = os.path.dirname(file_path)
if not os.path.exists(dir_name):
os.makedirs(dirp_name, RW_only)
# save data to file
with open(file_path, 'w') as f:
json.dump(data, f)
# change file permission mode to be 0x666
os.chmod(file_path, RW_only)
However, since python 3.7, the mode
argument no longer affects the file permission bits of newly-created intermediate-level directories, so solution 1 only works for old versions.
This is what I end up with: use process umask
Solution 2 [better]:
# mkdirs has mode 0777 by default, we get 0666 by masking out 0111
old_umask = os.umask(0111)
# create directory A/B/C
dir_name = os.path.dirname(file_path)
if not os.path.exists(dir_name):
os.makedirs(dirp_name)
# save data to file (file mode is 0666 by default)
with open(file_path, 'w') as f:
json.dump(data, f)
# restore old_umask
os.umask(old_umask)
Answered By - Yixing Liu Answer Checked By - Robin (WPSolving Admin)