题 递归设置文件权限的Python方式是什么?


什么是以递归方式将所有者和组设置为目录中的文件的“python方式”?我可以将'chown -R'命令传递给shell,但我觉得我错过了一些明显的东西。

我正在捣乱这个:


import os  
path = "/tmp/foo"  
for root, dirs, files in os.walk(path):  
  for momo in dirs:  
    os.chown(momo, 502, 20)

这似乎适用于设置目录,但在应用于文件时失败。我怀疑文件没有得到整个路径,因此chown失败,因为它无法找到文件。错误是:

'OSError:[Errno 2]没有这样的文件或目录:'foo.html'

我在这里俯瞰什么?


32
2018-05-17 23:45


起源




答案:


dirs 和 files 列表总是相对于 root  - 即,他们是 basename() 的文件/文件夹,即他们没有 / 在他们(或 \ 在窗户上)。你需要加入dirs /文件 root 如果你希望你的代码能够进行无限级别的递归,那么就可以得到它们的整个路径:

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)

我很惊讶 shutil 模块没有这个功能。


39
2018-05-18 00:41



这有一个我刚刚在我的同事的生产代码中看到的错误:-)指定的顶级目录不是chowned。我建议修改一个编辑,希望它得到批准。 - Avindra Goolcharan
所以我的编辑被拒绝了 - 好好看看任何使用它并遇到错误的人 /tmp/foo 没有更改其权限。很好地调节了蟒蛇人 - Avindra Goolcharan
@AvindraGoolcharan很好的抓住 - 希望这就是你的想法! - Jamieson Becker


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)

替代 aaa 和 bb 如你所愿


5
2018-05-18 00:25



如在接受的评论中, /tmp/foo 不会正确设置所有者。请参阅上面的评论。 - Avindra Goolcharan


尝试 os.path.join(root,momo) 这将给你完整的道路


4
2018-05-18 00:07





这是我写的一个函数,它使用glob来递归列出文件并更改其权限。

import os
import glob
def recursive_file_permissions(path,mode,uid=-1,gid=-1):
        '''
        Recursively updates file permissions on a given path.
        UID and GID default to -1, and mode is required
        '''
    for item in glob.glob(path+'/*'):
        if os.path.isdir(item):
            recursive_file_permissions(os.path.join(path,item),mode,uid,gid)
        else:
            try:
                os.chown(os.path.join(path,item),uid,gid)
                os.chmod(os.path.join(path,item),mode)
            except:
                print('File permissions on {0} not updated due to error.'.format(os.path.join(path,item)))

它不是完美的,但让我到达我需要的地方


2
2018-06-30 20:04





别忘了 for f in files 循环,或者。同样,请记住 os.path.join(root, f) 获得完整的路径。


1
2018-05-18 00:19





接受的答案错过了顶级文件。这实际相当于 chown -R

import os

path = "/tmp/foo"

os.chown(path, 502, 20)
for dirpath, dirnames, filenames in os.walk(path):
    for dname in dirnames:
        os.chown(os.path.join(dirpath, dname), 502, 20)
    for fname in filenames:
        os.chown(os.path.join(dirpath, fname), 502, 20)

0
2017-09-21 17:29





使用 os.lchown 代替 os.chown 对于 改变自己的联系 和文件在一起。


-2
2017-08-26 16:00