46

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

我在这里俯瞰什么?

4

10 回答 10

47

和列表总是相对于- 即dirs,它们是文件/文件夹的,即它们中(或在 Windows 上)没有。如果您希望代码工作到无限级别的递归,则需要加入 dirs/files 以获取它们的整个路径:filesrootbasename()/\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模块没有这个功能。

于 2010-05-18T00:41:11.253 回答
18

正如上面正确指出的那样,接受的答案错过了顶级文件和目录。其他答案使用os.walkthen 循环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)
于 2019-08-12T09:22:57.967 回答
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随你喜欢

于 2010-05-18T00:25:42.493 回答
4

试试os.path.join(root,momo)这会给你完整的路径

于 2010-05-18T00:07:57.030 回答
4

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

这是最简单的方法,并且有点迷失在问题中,所以为了清楚起见,如果您不关心 Windows,您可以在一行中执行此操作:

os.system('chown -R 502 /tmp/foo')
于 2019-08-14T18:30:58.870 回答
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)))

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

于 2011-06-30T20:04:12.797 回答
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)
于 2018-09-21T17:29:17.590 回答
1

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

于 2010-05-18T00:19:03.967 回答
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)
于 2021-01-16T01:24:01.997 回答
-2

使用而os.lchown不是更改链接本身和文件。os.chown

于 2013-08-26T16:00:30.147 回答