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

发布于 2024-09-02 02:29:15 字数 392 浏览 12 评论 0原文

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

我在这里忽略了什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

安穩 2024-09-09 02:29:15

dirsfiles 列表总是相对于 root - 即,它们是根目录的 basename()文件/文件夹,即它们中没有 / (或 Windows 上的 \)。如果您希望代码能够无限级递归,则需要将目录/文件连接到 root 以获得它们的完整路径:


import os  
path = "/tmp/foo"
    
# Change permissions for the top-level folder
os.chmod(path, 502, 20)

for root, dirs, files in os.walk(path):
  # set perms on sub-directories  
  for momo in dirs:
    os.chown(os.path.join(root, momo), 502, 20)

  # set perms on files
  for momo in files:
    os.chown(os.path.join(root, momo), 502, 20)

令人惊讶的是,shutil 模块并不这样做有这个功能。

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"
    
# Change permissions for the top-level folder
os.chmod(path, 502, 20)

for root, dirs, files in os.walk(path):
  # set perms on sub-directories  
  for momo in dirs:
    os.chown(os.path.join(root, momo), 502, 20)

  # set perms on files
  for momo in files:
    os.chown(os.path.join(root, momo), 502, 20)

Surprisingly, the shutil module doesn't have a function for this.

似最初 2024-09-09 02:29:15

正如上面正确指出的那样,接受的答案错过了顶级文件和目录。其他答案使用 os.walk ,然后循环遍历 dirnames 和 filenames 。但是,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)

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)
简单爱 2024-09-09 02:29:15

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

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

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

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')
喜爱皱眉﹌ 2024-09-09 02:29:15
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

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

小姐丶请自重 2024-09-09 02:29:15

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

try os.path.join(root,momo) that will give you full path

爱的那么颓废 2024-09-09 02:29:15

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

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

Here is a function i wrote that uses glob to recursively list files and change their permissions.

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)))

it's not perfect, but got me where I needed to be

赢得她心 2024-09-09 02:29:15

接受的答案错过了顶级文件。这实际上相当于 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)

The accepted answer misses top level files. This is the actual equivalent of 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)
话少心凉 2024-09-09 02:29:15

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

Don't forget the for f in files loop, either. Similarly, remember to os.path.join(root, f) to get the full path.

听你说爱我 2024-09-09 02:29:15
"""
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)
"""
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)
走野 2024-09-09 02:29:15

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

use os.lchown instead of os.chown for changing link themselves and files together.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文