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

时间:2010-05-17 23:45:18

标签: python recursion chown

以递归方式将所有者和组设置为目录中的文件的“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'

我在这里俯瞰什么?

10 个答案:

答案 0 :(得分:40)

dirsfiles列表都始终相对于root - 即,它们是文件/文件夹的basename(),即它们没有其中/(或Windows上的\)。如果您希望代码能够进行无限级别的递归,则需要将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模块没有此功能。

答案 1 :(得分:6)

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)

随意替换aaabb

答案 2 :(得分:4)

尝试os.path.join(root,momo),它将为您提供完整的路径

答案 3 :(得分:2)

这是我编写的一个函数,它使用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)))

它并不完美,但让我在需要的地方

答案 4 :(得分:2)

接受的答案会错过顶级文件。这实际上是与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)

答案 5 :(得分:2)

正如上面正确指出的,接受的答案会丢失顶级文件和目录。其他答案使用os.walk,然后遍历dirnamesfilenames。但是,os.walk无论如何都要经过dirnames,因此您可以跳过dirnames的循环,而仅跳过chown当前目录(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)

答案 6 :(得分:1)

也不要忘记for f in files循环。同样,请记住os.path.join(root, f)以获得完整路径。

答案 7 :(得分:0)

  

我可以将'chown -R'命令传递给shell

这是最简单的方法,并且会在问题中有所遗漏,因此为了清楚起见,如果您不关心Windows,则可以在一行中完成此操作:

os.system('chown -R 502 /tmp/foo')

答案 8 :(得分:0)

"""
Requires python 3
Accepts name or id
Usage:
  chown.py -p /temp/folder -u user  -g group -r true
  or
  chown.py -p /temp/folder -u uid -g gid -r 1
  user, group, and recursive are optional
  But must supply at least one of user or group
Example: sudo chown.py -p /temp/filename -u some_user 
"""
import argparse, os, sys
from shutil import chown
user = group = recursive = ''
parser=argparse.ArgumentParser()
parser.add_argument('-p', '--path')  # help='file/path'
parser.add_argument('-u', '--user')   # , help='user'
parser.add_argument( '-g','--group')   # , help='group'
parser.add_argument('-r', '--recursive', help=1)  # , help='recursive'

args=parser.parse_args()
path = args.path
if not path:
    raise Exception('missing path')
if args.user:
    user = args.user
if args.group:
    user = args.group
if args.recursive:
    recursive = True

if not user and not group:
    raise Exception('must supply user, group, or both')

def change_owner(path, user='', group='')
    if user and not group:
        chown(path, user=user)
    elif not user and group:
        chown(path, group=group)
    else:
        chown(path, user, group)

change_owner(path, user, group)
if recursive:
    for dirpath, dirnames, filenames in os.walk(path):
        for dname in dirnames:
            change_owner(os.path.join(dirpath, dname), user, group)
        for fname in filenames:
            change_owner(os.path.join(dirpath, fname), user, group)

答案 9 :(得分:-2)

使用os.lchown代替os.chown 自行更改链接和文件。