Подтвердить что ты не робот

Что такое способ Python для рекурсивного задания прав доступа к файлам?

Что такое "способ python", чтобы рекурсивно установить владельца и группу в файлы в каталоге? Я мог бы просто передать команду chown -R в оболочку, но я чувствую, что мне не хватает чего-то очевидного.

Я обманываю с этим:


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 '

Что я здесь не вижу?

4b9b3361

Ответ 1

Списки dirs и files всегда относятся к root, т.е. они являются basename() файлов/папок, то есть они не имеют / в них (или \ на окнах). Вам нужно присоединиться к файлам/файлам 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 не имеет функции для этого.

Ответ 2

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, как вам угодно

Ответ 3

попробуйте os.path.join(root,momo), который даст вам полный путь

Ответ 4

Вот функция, которую я написал, которая использует 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)))

это не идеально, но я получил там, где мне нужно было

Ответ 5

Принятый ответ не попадает в файлы верхнего уровня. Это фактический эквивалент 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)

Ответ 6

Не забудьте также цикл for f in files. Аналогично, запомните os.path.join(root, f), чтобы получить полный путь.

Ответ 7

Как правильно указано выше, принятый ответ пропускает файлы и каталоги верхнего уровня. Другие ответы используют 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)

Ответ 8

  Я мог бы просто передать команду 'chown -R' в оболочку

Это самый простой способ, и он немного теряется в вопросе, так что для ясности вы можете сделать это в одну строку, если вам нет дела до Windows:

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

Ответ 9

используйте os.lchown вместо os.chown для изменения самих ссылок и файлов.