What is the Python way for recursively setting file permissions?
Solution 1
The dirs
and files
lists are all always relative to root
- i.e., they are the basename()
of the files/folders, i.e. they don't have a /
in them (or \
on windows). You need to join the dirs/files to root
to get their whole path if you want your code to work to infinite levels of recursion:
import os
path = "/tmp/foo"
for root, dirs, files in os.walk(path):
for momo in dirs:
os.chown(os.path.join(root, momo), 502, 20)
for momo in files:
os.chown(os.path.join(root, momo), 502, 20)
I'm suprised the shutil
module doesn't have a function for this.
Solution 2
As correctly pointed out above, the accepted answer misses top-level files and directories. The other answers use os.walk
then loop through dirnames
and filenames
. However, os.walk
goes through dirnames
anyway, so you can skip looping through dirnames
and just chown
the current directory (dirpath
):
def recursive_chown(path, owner):
for dirpath, dirnames, filenames in os.walk(path):
shutil.chown(dirpath, owner)
for filename in filenames:
shutil.chown(os.path.join(dirpath, filename), owner)
Solution 3
import os
path = "/tmp/foo"
for root, dirs, files in os.walk(path):
for momo in dirs:
os.chown(momo, 502, 20)
for file in files:
fname = os.path.join(root, file)
os.chown(fname, aaa, bb)
substitute aaa
and bb
as you please
Solution 4
I could just pass a 'chown -R' command to shell
This is the simplest way, and gets lost in the question a bit, so just for clarity, you can do this in one line if you don't care about Windows:
os.system('chown -R 502 /tmp/foo')
Solution 5
try os.path.join(root,momo)
that will give you full path
Related videos on Youtube
Geoff
Updated on January 16, 2021Comments
-
Geoff over 3 years
What's the "python way" to recursively set the owner and group to files in a directory? I could just pass a 'chown -R' command to shell, but I feel like I'm missing something obvious.
I'm mucking about with this:
import os path = "/tmp/foo" for root, dirs, files in os.walk(path): for momo in dirs: os.chown(momo, 502, 20)
This seems to work for setting the directory, but fails when applied to files. I suspect the files are not getting the whole path, so chown fails since it can't find the files. The error is:
'OSError: [Errno 2] No such file or directory: 'foo.html'
What am I overlooking here?
-
Avindra Goolcharan over 8 yearsThis has a bug which I just saw in my co-worker's code in production :-) The top level directory specified is not being chowned. I suggested an edit with a fix, hopefully it gets approved.
-
Avindra Goolcharan over 8 yearsAs in the accepted comment,
/tmp/foo
will NOT have the owner properly set. See my comments above. -
Avindra Goolcharan over 8 yearsSo my edit was rejected - good look to anyone who uses this and encounters the bug where
/tmp/foo
does NOT have its permissions changed. Good job moderating SO pythonians 👍👍👍 -
fatal_error about 8 years@AvindraGoolcharan good catch - hopefully that was what you had in mind!
-
Christian Alis almost 5 yearsNo need to loop through
dirnames
sinceos.walk
will go through all directories anyway. See my answer. -
Christian Alis almost 5 years
-
gerardw over 3 yearsWhy shutil.chown instead of os.chown?
-
wedgef5 over 3 years@gerardw I believe os.chown() only takes numeric uid and gid, whereas shutil.chown() will accept names or numeric IDs.
-
jrh over 2 years@AvindraGoolcharan Edits 1, 2, strike 3 you're out. Apparently 9 reviewers think adding
os.chown(path, 502, 20)
"deviates from intent", "should be a comment", or "is worth making a whole new answer for". Really...? One line? Do all these people not know thatchmod -R some_dir
would changesome_dir
and all its child directories? I know you all are terrified about approving code edits, but still, this is silly